寫在最前面
- 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部默,否則就會出錯