原型链
Posted leftjs
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原型链相关的知识,希望对你有一定的参考价值。
原型链
https://www.cnblogs.com/pompey/p/6675559.html
https://www.cnblogs.com/alichengyin/p/4852616.html
prototype
javascript中所有的函数都有prototype这个属性
prototype是指向原型的引用
__proto__
对象的__proto__会指向其“构造函数”的prototype(先称之为构造函数)。
constructor
一个函数的原型的constructor属性指向的是函数本身
instanceof
instanceof是通过对象的prototype链来确定这个对象是否是某个类的实例,而不关心对象与类的自身结构。
js中创建对象的各种方法,现在最常用的方法是组合模式
1)原始模式
对象字面量方式
var person = {
name: ‘Jack’,
age: 18,
sayName: function () { alert(this.name); }
};
Object构造函数方式
var person = new Object();
person.name = ‘Jack’;
person.age = 18;
person.sayName = function () {
alert(this.name);
};
显然,当我们要创建批量的person1、person2……时,每次都要敲很多代码,资深copypaster都吃不消!然后就有了批量生产的工厂模式。
2)工厂模式
//2.工厂模式,定义一个函数创建对象
function creatPerson (name, age) {
var person = new Object();
person.name = name;
person.age = age;
person.sayName = function () {
alert(this.name);
};
return person;
}
工厂模式就是批量化生产,简单调用就可以进入造人模式(啪啪啪……)。指定姓名年龄就可以造一堆小宝宝啦,解放双手。但是由于是工厂暗箱操作的,所以你不能识别这个对象到底是什么类型、是人还是狗傻傻分不清(instanceof 测试为 Object),另外每次造人时都要创建一个独立的temp对象,代码臃肿,雅蠛蝶啊。
3)构造函数
//3.构造函数模式,为对象定义一个构造函数
function Person (name, age) {
this.name = name;
this.age = age;
this.sayName = function () {
alert(this.name);
};
}
var p1 = new Person(‘Jack’, 18); //创建一个p1对象
Person(‘Jack’, 18); //属性方法都给window对象,window.name=’Jack’,window.sayName()会输出Jack
构造函数与C++、JAVA中类的构造函数类似,易于理解,另外Person可以作为类型识别(instanceof 测试为 Person 、Object)。但是所有实例依然是独立的,不同实例的方法其实是不同的函数。这里把函数两个字忘了吧,把sayName当做一个对象就好理解了,就是说张三的 sayName 和李四的 sayName是不同的存在,但显然我们期望的是共用一个 sayName 以节省内存。
4)原型模式
//4.原型模式,直接定义prototype属性
function Person () {}
Person.prototype.name = ‘Jack’;
Person.prototype.age = 18;
Person.prototype.sayName = function () { alert(this.name); };
//4.原型模式,字面量定义方式
function Person () {}
Person.prototype = {
name: ‘Jack’,
age: 18,
sayName: function () { alert(this.name); }
};
var p1 = new Person(); //name=’Jack’
var p2 = new Person(); //name=’Jack’
这里需要注意的是原型属性和方法的共享,即所有实例中都只是引用原型中的属性方法,任何一个地方产生的改动会引起其他实例的变化。
5)混合模式(构造+原型)
//5. 原型构造组合模式,
function Person (name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
hobby: [‘running’,’football’];
sayName: function () { alert(this.name); },
sayAge: function () { alert(this.age); }
};
var p1 = new Person(‘Jack’, 20);
//p1:’Jack’,20; proto: [‘running’,’football’],sayName,sayAge
var p2 = new Person(‘Mark’, 18);
//p1:’Mark’,18;proto: [‘running’,’football’],sayName,sayAge
做法是将需要独立的属性方法放入构造函数中,而可以共享的部分则放入原型中,这样做可以最大限度节省内存而又保留对象实例的独立性。
扩展Object类,添加Clone和Extend方法
/*扩展Object类,添加Clone,JS实现克隆的方法*/
Object.prototype.Clone = function(){
var objClone;
if (this.constructor == Object){
objClone = new this.constructor();
}else{
objClone = new this.constructor(this.valueOf());
}
for(var key in this){
if ( objClone[key] != this[key] ){
if ( typeof(this[key]) == ‘object‘ ){
objClone[key] = this[key].Clone();
}else{
objClone[key] = this[key];
}
}
}
objClone.toString = this.toString;
objClone.valueOf = this.valueOf;
return objClone;
}
/*扩展Object类,添加Extend方法来实现JS继承, 目标对象将拥有源对象的所有属性和方法*/
Object.prototype.Extend = function (objDestination, objSource) {
for (var key in objSource) {
if (objSource.hasOwnProperty(key) && objDestination[key] === undefined) {
objDestination[key] = objSource[key];
}
}
return objDestination;
}
以上是关于原型链的主要内容,如果未能解决你的问题,请参考以下文章