您的位置:首页 > Web前端 > JavaScript

JS原型链

2016-05-26 09:32 537 查看
请将下面代码直接复制到浏览器console面板执行查看结果

console.log('');
console.log('');
console.log('***********************************构造函数声明***********************************************************');
console.warn('-------共有2个构造函数,其中MyObjectEx1、MyObjectEx2分别继承了MyObject-------');
console.warn('构造函数1: MyObject');
function MyObject() {
this.xxx = new Array();
}
MyObject.prototype.yyy = new Array();

console.warn('构造函数2: MyObjectEx1');

function MyObjectEx1() {
this.zzz = new Array();
}
MyObjectEx1.prototype = new MyObject();
MyObjectEx1.prototype.aaa = new Array();
MyObjectEx1.prototype.constructor = MyObjectEx1;
console.log('');
console.log('-----------------------实例化变量: MyObject------------------------------');
var obj1 = new MyObject();
var obj2 = new MyObject();
obj1.xxx.push('我是MyObject的公有属性zzz,我是obj1');
obj1.yyy.push('我是MyObject的原型属性yyy, 继承我的每个实例都有我这个属性');
obj2.xxx.push('我是MyObject的公有属性zzz,我是obj2');

console.warn("var obj1 = new MyObject();");
console.warn("var obj2 = new MyObject();");
console.warn("obj1.xxx.push('我是MyObject的公有属性zzz,我是obj1');");
console.warn("obj1.yyy.push('我是MyObject的原型属性yyy, 继承我的每个实例都有我这个属性');");
console.warn("obj2.xxx.push('我是MyObject的公有属性zzz,我是obj2');");
console.warn('-------------上面实例化变量后的结果打印-------------');
console.log('obj1:', obj1);
console.log('obj2:', obj2);

console.log('');
console.warn('-----------------------实例化变量: MyObjectEx1-----------------------');
var objEx1 = new MyObjectEx1();
var objEx2 = new MyObjectEx1();
console.warn("var objEx1 = new MyObjectEx1();");
console.warn("var objEx2 = new MyObjectEx1();");
console.warn('-------------改变objEx1和objEx2中属性的值-------------');
objEx1.zzz.push('我是MyObjectEx1的公有属性,我的值是objEx1');
objEx2.zzz.push('我是MyObjectEx1的公有属性,我的值是objEx2');
objEx1.xxx.push('通过objEx1向父类xxx添加一个元素');
objEx2.xxx.push('通过objEx2向父类xxx添加一个元素');
objEx1.yyy.push('通过objEx1向父类yyy添加一个元素');
objEx2.yyy.push('通过objEx2向父类yyy添加一个元素');
console.warn("objEx1.zzz.push('我是MyObjectEx1的公有属性,我的值是objEx1');");
console.warn("objEx2.zzz.push('我是MyObjectEx1的公有属性,我的值是objEx2');");
console.warn("objEx1.xxx.push('通过objEx1向父类xxx添加一个元素');");
console.warn("objEx2.xxx.push('通过objEx2向父类xxx添加一个元素');");
console.warn("objEx1.yyy.push('通过objEx1向父类yyy添加一个元素');");
console.warn("objEx1.yyy.push('通过objEx2向父类yyy添加一个元素');");
console.warn('-------------上面实例化变量后的结果打印-------------');
console.log('objEx1:', objEx1);
console.log('objEx2:', objEx2);

console.warn('由此可以看出对于继承关系节点中的每一个构造器中的公有属性,在其下属的构造器中(继承该构造器的子构造器),构造器公有属性体现为每个子类实例所持有的一个‘特殊’的属性,尽管大家都有这个属性,但是这个属性的值有该实例所持有,通过‘.’的方式直接对其取值或赋值,但是对不同的实例化对象,其可能是不同的,但是对于通过prototype定义的原型属性,对于所有的子类皆可以看做是一个‘局部全局变量’,可以当做引用来看,这是有区别的');


1.  原型链是一个由有限对象组成的对象链,用于实现继承和共享属性。

2. 对于instanceof这个关键字,更重要的意义是检查一个对象的归属问题,也即继承关系上归属,和创建该变量的类本省的关系不大,new 的过程其实更多的是体现继承关系(维护原型链)的,我们可以为实例对象维护obj.constructor属性的,让其指向类的构造器,从而实现最为完整的原型链效果,其次对于一个类而言,构造器(Function)持有一个prototype属性,当我们new出其实例对象之后,又将为其实例维护不可见属性__proto__属性,和类的prototype实现映射关系,对于__proto__属性,则体现了树的特点,每一个继承层级都有自己相应的属性和方法(使用原型的重要核心是继承树的建立。这一过程要求new运算符的参与,简单说来,就是"子类.prototype"必须赋值为"new
父类()"所产生的一个实例)

3. 对于typeof操作符,其强调后者的类型,所谓类型,也就是javascript的数据类型, 它的结果可能是String, Number, Function, Object(Null), Undefined, Boolean之一。
4. 所谓完整的原型继承链中的每一个类实例的继承层级关系树上都应该有自己的构造器函数,也就是说对于一个原型链中的所有的类都有构造函数时的原型链才是最完整的原型链,其次对于用关键字function修饰时(函数)才有prototype属性,因此可以看出,其实prototype就是用来集中体现类的扩展方法或继承关系。

5.  每一个变量或是对象都有__proto__属性,而且这个属性在大多数浏览器中是不可见的,只有手动方式才可以查看,__proto__属性是实例在原型链上的体现,任何对象都具有__proto__属性的,用来体现链的性质,最顶层则是Object。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息