JS(十四)原型辱志、原型鏈、call狞膘、apply揩懒、bind(下)

寫在最前面

  • proto指向的是是他的對象也就是prototype
  • prototype指向的是他的原型對象
  • constructor 指向的是他的構(gòu)造函數(shù)

proto是干什么用的

function Person(){
    
}
var person = new Person();

我們通過new的時候,里面經(jīng)歷了三段式

Person.prototype,name = "wu";
function Person(){
    //var this = {
    //    __proto__:Person.prototype
    //    __proto__指向的是他的原型
    //
    //}
}
var person = new Person();

因為proto指向的是他的原型,所以我們在person.name的時候,自己本身沒有,他才會通過這個proto這個屬性找到person.prototype上面去


修改原型

function Person(){
    
}

var obj = {
    name:"sunny";
}
var person = new Person();

person.__proto__ = obj;
person.name//打印出來"sunny",因為它的原型改了
Person.prototype.name = "sunny";
function Person(){
    
}
var person = new Person();
Person.prototype.name = 'cherry'

parson.name //打印出來"cherry"
//因為他的原型被改了

----------------分割線----------------
Person.prototype.name = "sunny";
function Person(){
    
}

Person.prototype.name = 'cherry'
var person = new Person();

parson.name //打印的還是"cherry"
//因為他的原型被改了

----------------分割線----------------

Person.prototype.name = "sunny";
function Person(){
    //var this = {__proto__ :Person.pertotype}
}

var person = new Person();
Person.prototype={
    name:cherry
}

parson.name //打印的是"sunny"
//類似這種,他把整個對象都給換了,而不是換的屬性
//Person.prototype = {name:"a"}
//__proto__ = Person.prototype 
//Person.prototype = {name:"b"}

-------分割線-----------------------------
Person.prototype.name = "sunny";
function Person(){
    //var this = {__proto__ :Person.pertotype}
}

Person.prototype={
    name:cherry
}

var person = new Person();

person.name//打印出cherry
//正常編譯;

原型鏈

  • 如何構(gòu)成原型鏈;
  • 原型鏈上屬性的增刪改查
  • 絕大多數(shù)對象的最終都會繼承自O(shè)bject.prototype
  • Object.create(原型)
function Person(){
    
}
Person.prototype
//打印出
Object{};
//里面有的屬性
constructor : Person();
__proto__ : Object;

//我們發(fā)現(xiàn)在prototype里面,他還有原型,說明原型他還有原型

原型鏈上的增刪改查和原型上的差不多,只能在自己的身上改,沒有辦法修改父級上面的...但是也不是完全不可以

最終原型

Grand.prototype.name = "shen"
function Grand(){
    
}
var grand = new Grand;

Father.prototype = grand;
function Father(){
    
}
var father = new Father;

son.prototype = father;
function son(){
    
}
var son = new Son();
son.name//打印出shen
//依次排查
Grand.prototype.__proto__ = object.prototype
//object.prototype最終原型
var obj = {};

var obj1 = new Object();
兩種寫法一樣;
//obj1.__proto__ --->Object.prototype


Person.pertotype = {}-->//object.prototype
function Person(){
    
}

Object.create : 就是一個新的對象可以繼承一個對象的屬性,并且可以自行添加屬性挽封。


//var Obj = Object.create(原型)
var Obj = {
    name = "sunny",
    age : 123
};
var obj1 = Object.create(obj);

obj1.name//打印出sunny

添加屬性

var parents = {
     name : "wu",
     bron : "2013",
     from : "China"
 }
 var child = Object.create(
     parents,
     {
         title : {
             value : "技術(shù)分享",
 
         },
         year : {
             value : "18",
 
         }
     }
 );

特殊情況

var a = object.create(null)
//這種情況他就沒有原型

call\apply\bind

  • JavaScript 提供了call已球、apply、bind這三個方法辅愿,來切換/固定this的指向智亮。
  • 作用,改變this指向;
  • 區(qū)別,后面?zhèn)鞯膮?shù)不同
function Person(name,age){
    //this == obj;
    this.name = name;
    this.age = age;
}

var person = new Person("shen" 150);
var obj = {};
Person.call(obj,"wu",200);

函數(shù)實例的call方法,可以指定函數(shù)內(nèi)部this的指向(即函數(shù)執(zhí)行時所在的作用域)点待,然后在所指定的作用域中阔蛉,調(diào)用該函數(shù)

var obj = {};

var f = function () {
  return this;
};

f() === window // true
f.call(obj) === obj // true

上面代碼中,全局環(huán)境運行函數(shù)f時亦鳞,this指向全局環(huán)境(瀏覽器為window對象)馍忽;call方法可以改變this的指向棒坏,指定this指向?qū)ο髈bj燕差,然后在對象obj的作用域中運行函數(shù)f

在舉個例子

var n = 123;
var obj = { n: 456 };

funcion a() {
  console.log(this.n);
}

a.call() // 123
a.call(null) // 123
a.call(undefined) // 123
a.call(window) // 123
a.call(obj) // 456

上面代碼中,a函數(shù)中的this關(guān)鍵字坝冕,如果指向全局對象徒探,返回結(jié)果為123。如果使用call方法將this關(guān)鍵字指向obj對象喂窟,返回結(jié)果為456测暗。可以看到磨澡,如果call方法沒有參數(shù)碗啄,或者參數(shù)為null或undefined,則等同于指向全局對象稳摄。

Function.prototype.apply()

apply方法的作用與call方法類似稚字,也是改變this指向,然后再調(diào)用該函數(shù)厦酬。唯一的區(qū)別就是胆描,它接收一個數(shù)組作為函數(shù)執(zhí)行時的參數(shù),使用格式如下仗阅。

func.apply(thisValue, [arg1, arg2, ...])

apply方法的第一個參數(shù)也是this所要指向的那個對象昌讲,如果設(shè)為null或undefined,則等同于指定全局對象减噪。第二個參數(shù)則是一個數(shù)組短绸,該數(shù)組的所有成員依次作為參數(shù)车吹,傳入原函數(shù)。原函數(shù)的參數(shù)醋闭,在call方法中必須一個個添加礼搁,但是在apply方法中,必須以數(shù)組形式添加目尖。

function f(x, y){
  console.log(x + y);
}

f.call(null, 1, 1) // 2
f.apply(null, [1, 1]) // 2

上面代碼中馒吴,f函數(shù)本來接受兩個參數(shù),使用apply方法以后瑟曲,就變成可以接受一個數(shù)組作為參數(shù)饮戳。

Function.prototype.bind()

bind方法用于將函數(shù)體內(nèi)的this綁定到某個對象,然后返回一個新函數(shù)

var d = new Date();
d.getTime() // 1481869925657

var print = d.getTime;
print() // Uncaught TypeError: this is not a Date object.

上面代碼中洞拨,我們將d.getTime方法賦給變量print扯罐,然后調(diào)用print就報錯了。這是因為getTime方法內(nèi)部的this烦衣,綁定Date對象的實例歹河,賦給變量print以后,內(nèi)部的this已經(jīng)不指向Date對象的實例了

bind方法可以解決這個問題花吟。

var print = d.getTime.bind(d);
print() // 1481869925657

上面代碼中秸歧,bind方法將getTime方法內(nèi)部的this綁定到d對象,這時就可以安全地將這個方法賦值給其他變量了衅澈。

bind方法的參數(shù)就是所要綁定this的對象键菱,下面是一個更清晰的例子。

var counter = {
  count: 0,
  inc: function () {
    this.count++;
  }
};

var func = counter.inc.bind(counter);
func();
counter.count // 1

上面代碼中今布,counter.inc方法被賦值給變量func经备。這時必須用bind方法將inc內(nèi)部的this,綁定到counter部默,否則就會出錯

PS : 后面call\apply\bind方法是借的阮一峰 阮大神的JavaScript標(biāo)準(zhǔn)考教 非商業(yè)用途

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末侵蒙,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子傅蹂,更是在濱河造成了極大的恐慌纷闺,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,406評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件贬派,死亡現(xiàn)場離奇詭異急但,居然都是意外死亡,警方通過查閱死者的電腦和手機搞乏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,732評論 3 393
  • 文/潘曉璐 我一進店門波桩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人请敦,你說我怎么就攤上這事镐躲〈⒚担” “怎么了?”我有些...
    開封第一講書人閱讀 163,711評論 0 353
  • 文/不壞的土叔 我叫張陵萤皂,是天一觀的道長撒穷。 經(jīng)常有香客問我,道長裆熙,這世上最難降的妖魔是什么端礼? 我笑而不...
    開封第一講書人閱讀 58,380評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮入录,結(jié)果婚禮上蛤奥,老公的妹妹穿的比我還像新娘。我一直安慰自己僚稿,他們只是感情好凡桥,可當(dāng)我...
    茶點故事閱讀 67,432評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蚀同,像睡著了一般缅刽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蠢络,一...
    開封第一講書人閱讀 51,301評論 1 301
  • 那天衰猛,我揣著相機與錄音,去河邊找鬼谢肾。 笑死腕侄,一個胖子當(dāng)著我的面吹牛小泉,可吹牛的內(nèi)容都是我干的芦疏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,145評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼微姊,長吁一口氣:“原來是場噩夢啊……” “哼酸茴!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起兢交,我...
    開封第一講書人閱讀 39,008評論 0 276
  • 序言:老撾萬榮一對情侶失蹤薪捍,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后配喳,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體酪穿,經(jīng)...
    沈念sama閱讀 45,443評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,649評論 3 334
  • 正文 我和宋清朗相戀三年晴裹,在試婚紗的時候發(fā)現(xiàn)自己被綠了被济。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,795評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡涧团,死狀恐怖只磷,靈堂內(nèi)的尸體忽然破棺而出经磅,到底是詐尸還是另有隱情,我是刑警寧澤滤灯,帶...
    沈念sama閱讀 35,501評論 5 345
  • 正文 年R本政府宣布沪哺,位于F島的核電站建炫,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏轧叽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,119評論 3 328
  • 文/蒙蒙 一刊棕、第九天 我趴在偏房一處隱蔽的房頂上張望犹芹。 院中可真熱鬧,春花似錦鞠绰、人聲如沸腰埂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,731評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽屿笼。三九已至,卻和暖如春翁巍,著一層夾襖步出監(jiān)牢的瞬間驴一,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,865評論 1 269
  • 我被黑心中介騙來泰國打工灶壶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留肝断,地道東北人。 一個月前我還...
    沈念sama閱讀 47,899評論 2 370
  • 正文 我出身青樓驰凛,卻偏偏與公主長得像胸懈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子恰响,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,724評論 2 354

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