js中原型链理解
本文固定连接:https://blog.****.net/u011135729/article/details/79813174
假设有这么一段代码:
function fn(){
this.prop = {};
}
var o = new fn();
console.log(o.__proto__ === fn.prototype); //true
console.log(fn.prototype.__proto__ === Object.prototype); //true
console.log(Object.prototype.__proto__); //null
1、o.__proto__ ---> fn.prototype,
2、fn.prototype.__proto__ ---> Object.prototype
3、Object.prototype.__proto__ ---null 原型链结束
例如:
//es5中才有的Object.create,这里先这样兼容一下吧(可以参考最下方的参考链接查看兼容的浏览器)
if (typeof Object.create !== "function") {
Object.create = function (proto, propertiesObject) {
if (typeof proto !== 'object' && typeof proto !== 'function') {
throw new TypeError('Object prototype may only be an Object: ' + proto);
} else if (proto === null) {
throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");
}
if (typeof propertiesObject != 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");
function F() {}
F.prototype = proto;
return new F();
};
}
function grandpa(name){
this.name = name;
}
grandpa.prototype = {
getName : function(){
console.log('my name is '+this.name);
}
}
function father(name){
grandpa.call(this,name);
}
father.prototype = Object.create(grandpa.prototype);
father.prototype.constructor = father;
function son(name){
father.call(this,name);//这样写目的是让son的实例也拥有父类函数内部的属性与方法(非prototype);
};
son.prototype = Object.create(father.prototype);
son.prototype.constructor = son;//这样的是将实例的construction指向son 即 实例.constructor 的值为 ‘function son(name){father.call(this,name);}’
var sonModel = new son('son');
console.log(sonModel.name);//son
sonModel.getName();//my name is son
原型链在属性搜索中的作用:
寻找一个属性会遍历整条原型链
Object.prototype.d = 4;
function fn(){
this.a = 1;
}
fn.prototype.b = 2;
fn.prototype.c = 3;
function fn2(){
fn.call(this);
this.c = 'fn2中的c';
}
fn2.prototype = Object.create(fn.prototype);
var fn2Model = new fn2();
console.log(fn2Model.c); //fn2中的c
console.log(fn2Model.d); //4
上面这段代码,fn2Model对象本身只有a c两个属性(直接被注册到this上了),同时,在fn.prototype中b c两个属性被继承,但最后fn2Model.c的值为‘fn2中的c’,fn2Model.d的值为4,可以得出结论
属性的搜索机制:先搜索实例对象本身具有的属性(如果写法中在子类内部不写 父类.call(this) ,那么可以理解为是方法内部的属性),找到则返回,找不到则会找原型,一次顺着原型链依次向上查找,直到原型链结束。
包括枚举一个实例对象时候,也会通过原型链查找到原型链结束 即Object.prototype.__proto__
Object.prototype.d = 4;
function fn(){
this.a = 1;
this.b = 2;
}
fn.prototype.c = 3;
fn.prototype.getName = function(){
console.log(this.a+this.b+this.c+this.d);
};
var o = new fn();
for(var item in o){
console.log(item);//打印结果 a b c getName d
}
o.getName();//10
本文固定连接:https://blog.****.net/u011135729/article/details/79813174
参考链接:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create