JS對(duì)象學(xué)習(xí)筆記

1.創(chuàng)建對(duì)象(兩種)

(1)//普通創(chuàng)建
var person = new Object();
// var person = {}//簡(jiǎn)寫(xiě)
//函數(shù)封裝--工廠(chǎng)方式
function createPerson(name) {
    //特點(diǎn):流水線(xiàn)生產(chǎn)
    //原材料
    var person = new Object();
    //加工
    person.name = name;
    person.showName = function () {
        console.log(this.name)
    }
    //出產(chǎn)品
    return person;//返回對(duì)象,否則無(wú)法創(chuàng)建擎厢,為undefine
}
var p1 = createPerson("huahua");//封裝方式的創(chuàng)建
p1.showName();打印
(2)//new方法創(chuàng)建即構(gòu)造函數(shù)創(chuàng)建
new關(guān)鍵字作用
/**
1.創(chuàng)建一個(gè)新對(duì)象
2.將構(gòu)造函數(shù)的作用域賦給新對(duì)象(因此究流,this就指向了這個(gè)新對(duì)象)
3.指向鉤子函數(shù)中的代碼(為這個(gè)新對(duì)象添加屬性)
4.返回新對(duì)象(不用寫(xiě)return)
*/
//改寫(xiě)如下
//構(gòu)造函數(shù)無(wú)返回值
function CreatePerson(name){
    this.name = name
    this.showName = function(){
        alert(this.name)
    }
}

2.對(duì)象引用

//基本類(lèi)型
    var num1 = 20;
    var num2 = num1;
    console.log(num1)//20
//引用類(lèi)型
var arr1 = [1, 2, 3];
var arr2 = arr1;
arr2.push(4);
console.log(arr1)//[1,2,3,4]發(fā)生了改變

如果從一個(gè)變量向另一個(gè)變量復(fù)制引用類(lèi)型的值,同樣還是會(huì)將存儲(chǔ)在變量對(duì)象中的值復(fù)制一份放到新變量分配的空間中动遭,不同的是芬探,復(fù)制的這個(gè)副本是一個(gè)指針,并不是具體的對(duì)象厘惦,這個(gè)指針指向存儲(chǔ)在堆內(nèi)存中的一個(gè)對(duì)象偷仿,復(fù)制操作結(jié)束后,兩個(gè)變量實(shí)際上將引用同一個(gè)對(duì)象

引用類(lèi)型

3.原型(prototype)的使用
我們創(chuàng)建的每一個(gè)函數(shù)都有一個(gè)prototype(原型)屬性宵蕉,這個(gè)屬性是一個(gè)指針酝静,指向一個(gè)對(duì)象,而這個(gè)對(duì)象的用途是包含可以由特定類(lèi)型的所有實(shí)例共享的屬性和方法羡玛,這個(gè)對(duì)象就是構(gòu)造函數(shù)CreatePerson的原型對(duì)象别智,當(dāng)調(diào)用CreatePerson創(chuàng)建出一個(gè)具體對(duì)象p1后,p1內(nèi)部也有一個(gè)指針指向構(gòu)造函數(shù)的原型對(duì)象稼稿,同樣的道理亿遂,不管創(chuàng)建出多少對(duì)象,這些對(duì)象內(nèi)部都會(huì)有個(gè)指針執(zhí)行構(gòu)造函數(shù)的原型對(duì)象渺杉,使用原型對(duì)象的好處是讓所有被創(chuàng)建出來(lái)的對(duì)象共享這個(gè)原型對(duì)象所包含的屬性和方法

function CreatePerson(name){
    this.name = name
}
//  每個(gè)函數(shù)都有一個(gè)prototype對(duì)象,即指針(對(duì)象的指針指向prototype對(duì)象的地址)挪钓,指向一個(gè)對(duì)象(原型對(duì)象)
//創(chuàng)建出來(lái)的對(duì)象是越,也指向原型對(duì)象
CreatePerson.prototype.showName = function(){
    alert(this.name)
}
var p1 = new CreatePerson("小強(qiáng)")
var p2 = new CreatePerson("小花")
var p3 = new CreatePerson("小豆")
alert(p1.showName === p2.showName) // true
alert(p2.showName === p3.showName) // true
//    錯(cuò)誤演示
    console.log(p1.prototype)//undeifined,原型是在構(gòu)造函數(shù)上的且不可見(jiàn)的!!!

//瀏覽器產(chǎn)商 Chrome firefox自己實(shí)現(xiàn)了prototype可見(jiàn),但不是標(biāo)準(zhǔn)B瞪稀倚评!!
有些瀏覽器沒(méi)得
 console.log(p1.__proto__);//下劃線(xiàn)左右兩個(gè),p1.__proto__指向原型對(duì)象
原型使用
面向?qū)ο筮x項(xiàng)卡:
//面向過(guò)程版的:
var oWrap = document.getElementById("wrap");
var aBtn = oWrap.getElementsByTagName("button")
var aDiv = oWrap.getElementsByTagName("div")
for(var i=0; i<aBtn.length;i++){
    aBtn[i].index = i
    aBtn[i].onmouseover = function () {
        for(var j=0;j<aBtn.length;j++){
            aBtn[j].style.backgroundColor = "white"
            aDiv[j].style.display = "none"
        }
        this.style.backgroundColor = "orangered"
        aDiv[this.index].style.display = "block"
    }
}
//面向?qū)ο蟀娴模?/1./把面向過(guò)程的代碼整理浦徊,功能封裝
//   2.面向?qū)ο笸晟?//       (1).全局變量就是屬性 (2).函數(shù)就是方法(3).既不是全局和函數(shù),就封裝成初始化方法
//3天梧、調(diào)整this指向(出現(xiàn)嵌套代碼塊盔性,一般this指向不同)
//id用來(lái)代表多個(gè)選項(xiàng)卡中選中的一個(gè)
    function Tab(id) {
        this.oWrap = document.getElementById(id);
        this.aBtn = this.oWrap.getElementsByTagName("button");
        this.aDiv = this.oWrap.getElementsByTagName("div");

    }

//記得加this,指向
Tab.prototype.changeTab = function (obj) {
    for(var j=0;j<this.aBtn.length;j++){
        this.aBtn[j].style.backgroundColor = "white"
        this.aDiv[j].style.display = "none"
    }
    obj.style.backgroundColor = "orangered"
    this.aDiv[obj.index].style.display = "block"
}
//初始化方法
  Tab.prototype.init = function () {
    var That = this
    for(var i=0; i<this.aBtn.length;i++){
        this.aBtn[i].index = i;
        console.log("外層",this)
        this.aBtn[i].onmouseover = function () {
            That.changeTab(this)
            console.log("內(nèi)層",this)
        }
    }
}
//創(chuàng)建對(duì)象呢岗,調(diào)用
var t1 = new Tab("wrap")
    t1.init()
    var t2 = new Tab("wrap2")
    t2.init()

3.包裝對(duì)象
字符串為啥可以使用:charAt冕香、indexOf、replace等方法后豫?
-----基本類(lèi)型都有其對(duì)應(yīng)的一個(gè)包裝對(duì)象悉尾,例如:字符串類(lèi)型對(duì)應(yīng)的包裝對(duì)象是String,數(shù)字的包裝對(duì)象是Number挫酿,布爾類(lèi)型對(duì)應(yīng)的包裝對(duì)象是Boolean构眯。根據(jù)原型知識(shí),我們可以猜測(cè)一下charAt可能是掛載到String構(gòu)造函數(shù)原型上的早龟,所以當(dāng)str對(duì)象去調(diào)用charAt方法是可以正常運(yùn)行的

String.prototype.charAt = function(){}
//給String構(gòu)造函數(shù)自定義一個(gè)方法惫霸,看普通的字符串是否也能夠使用
//創(chuàng)建一個(gè)字符串對(duì)象
var str1 = new String("hello")
String.prototype.test = function(){
    alert(1)
}
//創(chuàng)建一個(gè)基本類(lèi)型字符串
var str2 = "hello2"
str2.test()  // 彈出1
//如果給str2掛載一個(gè)屬性,看看效果
str2.num = 10
alert(str2.num) // undefined
//從上面的代碼我們知道了 基本類(lèi)型的str2可以使用方法葱弟,實(shí)際上使用的是String身上的方法
上面代碼實(shí)際上執(zhí)行了以下幾個(gè)步驟:
1.創(chuàng)建String 類(lèi)型的對(duì)象
2.在對(duì)象上調(diào)用指定的方法
3.銷(xiāo)毀這個(gè)對(duì)象

4.原型鏈:
原型鏈就是實(shí)例對(duì)象和原型之間的鏈接壹店。每個(gè)函數(shù)都有一個(gè)prototype屬性,這個(gè)prototype指向一個(gè)對(duì)象(利用包裝對(duì)象.prototype.方法名 = function(){}創(chuàng)建的方法)翘悉,這個(gè)對(duì)象叫做原型茫打,通過(guò)構(gòu)造函數(shù)創(chuàng)建出來(lái)的實(shí)例也有一個(gè)內(nèi)部指針指向原型,這樣就形成實(shí)例對(duì)象和原型直接的鏈接妖混,我們把這個(gè)鏈接稱(chēng)為原型鏈老赤。

原型鏈的層級(jí)關(guān)系

原型鏈有多層,最外層為Object.prototype

function Fn1(){
this.num = 10;
}
Fn1.prototype.num = 20
Object.prototype.num = 30
var f1 = new Fn1()
console.log(f1.__proto__)
console.log(f1.__proto__.__proto__.num)  //30
-------------------------------------------------------------------------------------------------
//es6 中獲取原型制市,取代__proto__的方法Object.getPrototypeOf(對(duì)象實(shí)例)
    console.log(Object.getPrototypeOf(f1) === f1.__proto__);//true
//注意:prototype 是在構(gòu)造函數(shù)上抬旺,__proto__在對(duì)象上

//訪(fǎng)問(wèn)屬性的優(yōu)先級(jí)---就近原則,例如:f1祥楣,F(xiàn)n.prototype, Object.prototype上都有num屬性开财,
//那么alert(f1.num)的時(shí)候,首先取出的是f1身上的值误褪,如果f1身上沒(méi)有责鳍,那么才訪(fǎng)問(wèn)Fn.prototype,
//以此類(lèi)推,訪(fǎng)問(wèn)到最外層Object.prototype兽间,如果最終都沒(méi)有就返回undefined
alert(f1.num)
控制臺(tái)
關(guān)系圖

5.面向?qū)ο蟮南嚓P(guān)屬性和方法

//hasOwnProperty
    function Fn() {
     this.name = 20;
    }
    Fn.prototype.age = 40;
    var f1 = new Fn();
    alert(f1.hasOwnProperty("name"))//true
    alert(f1.hasOwnProperty("age"))//false
    alert(Fn.hasOwnProperty("name"))//true
//constructor
    console.log(f1.constructor)//查看該對(duì)象的構(gòu)造函數(shù)
    console.log(Fn.prototype.constructor)

function Fn1(){}
// 指向Fn1的
    Fn1.prototype.name = 10
    Fn1.prototype.age = 20
  // 指向Object的历葛,把一個(gè)對(duì)象賦值給原型對(duì)象,被后面的對(duì)象覆蓋了
    Fn1.prototype = {
        name: 10,
        age: 20
    }
    // 指向Object
    console.log(Fn1.prototype.constructor)
 // 當(dāng)一個(gè)構(gòu)造函數(shù)新創(chuàng)建出來(lái)后嘀略,會(huì)自動(dòng)生成下面一句話(huà)
 Fn1.prototype.constructor = Fn1
    // 上面的寫(xiě)法不經(jīng)意間就會(huì)把constructor修改掉,因此,我們需要手動(dòng)去修正
    function Fn1(){}
    Fn1.prototype = {
        constructor: Fn1,
        name: 10,
        age: 20
    }
    // 指向Fn1
    console.log(Fn1.prototype.constructor)
//自己添加的num屬性是可以被打印出來(lái)的最域,系統(tǒng)自帶的沒(méi)辦法for in循環(huán)出來(lái)
    Fn1.prototype.num = 10
    for(var attr in Fn1.prototype){
        console.log(attr)   //把constructor name age num屬性打印了一遍,沒(méi)打印值
    }

//instanceof 用來(lái)測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的 prototype 屬性
alert(f1 instanceof Fn1)  //true
alert(f1 instanceof Array) //false

//toString()
//    toStringtoString的作用是把對(duì)象轉(zhuǎn)換成字符串鸠天,如果是系統(tǒng)自帶的對(duì)象去調(diào)用toString方法, 那么toString方法在原型對(duì)象上帐姻,如果不是系統(tǒng)自帶的對(duì)象去調(diào)用toString方法稠集,那么toString在Object.prototype上
    var arr =[1,2,3]
//    調(diào)用的是Array.prototype原型對(duì)象上的toString();
console.log(arr.toString())
    console.log(f1)//toSting()在Object上
//    改寫(xiě)應(yīng)用與分割字符
    Array.prototype.toString = function () {
        return this.join("-")
    }
    console.log(arr.toString())
//轉(zhuǎn)換16進(jìn)制顏色
    var num1 = 255;
    console.log(num1.toString(16))//打印ff

//判斷類(lèi)型(推薦第三種)
 //    判斷類(lèi)型方法 consructor instanceof toString
    var arr=[]
    console.log(arr.constructor == Array)//true
    console.log(arr.prototype)//undefined
    console.log(arr.prototype  instanceof Array)//false
    console.log(arr instanceof Array)//true
    console.log(arr.toString() === Array)//false
    // //call(對(duì)象)改變內(nèi)部this指向,應(yīng)用某一對(duì)象的一個(gè)方法卖宠,用另一個(gè)對(duì)象替換當(dāng)前對(duì)象
    console.log(Object.prototype.toString.call(arr))//[object Array]
    console.log(Object.prototype.toString.call())//[object Undefined] 因?yàn)闆](méi)有傳入
console.log(Object.prototype.toLocaleString.call(arr))//1-2-3

6.call()方法和apply()方法巍杈。都是調(diào)用一個(gè)對(duì)象的一個(gè)方法,以另一個(gè)對(duì)象替換當(dāng)前對(duì)象扛伍,可以理解為借用一個(gè)對(duì)象的方法筷畦。傳參形式不同!

   function Fn1(){

    }
    function Fn2(){

    }
   Fn1.prototype.showAge = function (age,age2) {
       alert(age)
       alert(age2)
   }
var f1 = new Fn1()
    var f2 = new Fn2()
    f1.showAge(20);
    f1.showAge.apply(f2)//undefind
    f1.showAge.call(f2,20,63)//多個(gè)分隔開(kāi)
    f1.showAge.apply(f2,[20,23])//可傳多個(gè)參數(shù),多個(gè)用數(shù)組

7.繼承

function Parent(name, age) {
        this.name = name;
        this.age = age;
    }
    Parent.prototype.showName = function () {
        alert(this.name)
    };
    function Child(name, age) {
//Parent里面的this指向會(huì)出現(xiàn)問(wèn)題刺洒,直接調(diào)用Parent()函數(shù)鳖宾,相當(dāng)于window.Parent(),那么函數(shù)里面的this是指向window的,這個(gè)時(shí)候逆航,我們需要修正Parent里面的this鼎文,讓Parent里面的this指向Child才行
      //Parent.call(name, age)
  //不能具體指明對(duì)象,new的對(duì)象因俐,很多且不同
        Parent.call(this, name, age)
    }
//繼承方法拇惋,把Parent的原型賦值給Child原型
//對(duì)象引用,兩個(gè)對(duì)象指向同一個(gè)地址抹剩,撑帖,任何一個(gè)對(duì)象的修改都會(huì)影響另一個(gè)對(duì)象
//    Child.prototype = Parent.prototype;
    //影響:父中和子中都有同樣的方法。解決如下:
function extend(obj1,obj2){
        //循環(huán)obj2的內(nèi)容澳眷,賦給obj1胡嘿。for in專(zhuān)門(mén)循環(huán)對(duì)象
        for (var attr in obj2) {
            obj1[attr] = obj2[attr]
        }
    }
//封裝extend方法的原因,直接對(duì)象賦值給對(duì)象的話(huà)钳踊,會(huì)造成對(duì)象的引用衷敌,兩者相互影響
    Child.prototype.showAge = function () {
        alert(this.age)
    };
    var c1 = new Child("小紅", 222)
    c1.showName()
    c1.showAge()
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市拓瞪,隨后出現(xiàn)的幾起案子缴罗,更是在濱河造成了極大的恐慌,老刑警劉巖祭埂,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瞒爬,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)侧但,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)航罗,“玉大人禀横,你說(shuō)我怎么就攤上這事≈嘌” “怎么了柏锄?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵复亏,是天一觀的道長(zhǎng)趾娃。 經(jīng)常有香客問(wèn)我,道長(zhǎng)缔御,這世上最難降的妖魔是什么抬闷? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮耕突,結(jié)果婚禮上笤成,老公的妹妹穿的比我還像新娘。我一直安慰自己眷茁,他們只是感情好炕泳,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著上祈,像睡著了一般培遵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上登刺,一...
    開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
  • 那天籽腕,我揣著相機(jī)與錄音,去河邊找鬼塘砸。 笑死节仿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的掉蔬。 我是一名探鬼主播廊宪,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼女轿!你這毒婦竟也來(lái)了箭启?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蛉迹,失蹤者是張志新(化名)和其女友劉穎傅寡,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡荐操,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年芜抒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片托启。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡宅倒,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出屯耸,到底是詐尸還是另有隱情拐迁,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布疗绣,位于F島的核電站线召,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏多矮。R本人自食惡果不足惜缓淹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望工窍。 院中可真熱鬧割卖,春花似錦、人聲如沸患雏。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)淹仑。三九已至丙挽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間匀借,已是汗流浹背颜阐。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吓肋,地道東北人凳怨。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像是鬼,于是被迫代替她去往敵國(guó)和親肤舞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容