javascript中面向对象之原型链解析
来源:互联网 发布:天谕女角色捏脸数据 编辑:程序博客网 时间:2024/05/20 10:52
任何一个对象都有一个prototype的属性,在js中可以把它记为:__proto_
当初ECMAscript的发明者为了简化这门语言,同时又保持继承的属性,于是就设计了这个链表。。
在数据结构中学过链表不,链表中有一个位置相当于指针,指向下一个结构体。
于是乎__proto__也一样,每当你去定义一个prototype的时候,相当于把该实例的__proto__指向一个结构体,那么这个被指向结构体就称为该实例的原型。
文字说起来有点儿绕,看图说话
var foo = {
x: 10,
y: 20
};
当我不指定__proto__的时候,foo也会预留一个这样的属性,
如果有明确的指向,那么这个链表就链起来啦。
很明显,下图中b和c共享a的属性和方法,同时又有自己的私有属性。
__proto__默认的也有指向。它指向的是最高级的object.prototype,而object.prototype的__proto__为空。
var a = {
x: 10,
calculate: function (z) {
return this.x + this.y + z
}
};
var b = {
y: 20,
__proto__: a
};
var c = {
y: 30,
__proto__: a
};
// call the inherited method
b.calculate(30); // 60
理解了__proto__这个属性链接指针的本质。。再来理解constructor。
当定义一个prototype的时候,会构造一个原形对象,这个原型对象存储于构造这个prototype的函数的原形方法之中.
function Foo(y){
this.y = y ;
}
Foo.prototype.x = 10;
Foo.prototype.calculate = function(z){
return this.x+this.y+z;
};
var b = new Foo(20);
alert(b.calculate(30));
在 JavaScript 中,每个函数都有名为prototype的属性,用于引用原型对象。此原型对象又有名为constructor的属性,它反过来引用函数本身。这是一种循环引用, 下图更好地说明了这种循环关系。
图1 循环关系
现在,通过new运算符用函数(上面示例中为 person)创建对象时,所获得的对象将继承 person.prototype 的属性。在上图,可以看到 person.prototype 对象有一个回指 person 函数的构造函数属性。这样,每个 person对象(从 person.prototype 继承而来)都有一个回指 person 函数的构造函数属性。
我们可以用以下代码来验证这种循环是否正确:function person(name, age) {
this.name = name;
this.age = age;
}
person.prototype.getInfo = function() {
alert("My name is "+this.name+", and I have "+this.age+" years old");
}
var zhangchen = new person("zhangchen", 23);
alert(zhangchen.constructor == person.prototype.constructor); //output true
alert(zhangchen.constructor == person);// output true
alert(person.prototype.isPrototypeOf(zhangchen)); //output true
以上代码中的对"isPrototypeOf()"方法的调用来自哪里呢?是来自person.prototype对象吗?不对,实际上,在 person.prototype 和 person 实例中还可以调用其他方法,比如 toString、toLocaleString 和 valueOf,但它们都不来自 person.prototype。而是来自于JavaScript 中的 Object.prototype ,它是所有原型的最终基础原型。(Object.prototype 的原型是 null。)
在以上例中,zhangchen.prototype 是对象。它是通过调用 Object 构造函数创建的(尽管它不可见)相当于执行子以下代码:
zhangchen.prototype = new Object();
因此,正如 person实例继承person.prototype 一样,zhangchen.prototype 继承 Object.prototype。这使得所有 zhangchen 实例也继承了 Object.prototype 的方法和属性。
原型链:每个 JavaScript 对象都继承一个原型链,而所有原型都终止于 Object.prototype。注意,这种继承是活动对象之间的继承。它不同于继承的常见概念,后者是指在声明类时类之间的发生的继承。因此,JavaScript 继承动态性更强。它使用简单算法实现这一点,如下所示:当您尝试访问对象的属性/方法时,JavaScript 将检查该属性/方法是否是在该对象中定义的。如果不是,则检查对象的原型。如果还不是,则检查该对象的原型的原型,如此继续,一直检查到 Object.prototype。下图说明了此解析过程:
从以上解析过程中,如果在对象中定义了属性/方法 X,则该对象的原型中将隐藏同名的属性/方法。例如,通过在 person.prototype 中定义 toString 方法,可以改写 Object.prototype 的 toString 方法。
再看以下代码:function person(name, age) {
this.name = name;
this.age = age;
}
person.prototype.getInfo = function() {
alert("My name is "+this.name+", and I have "+this.age+" years old");
}
var zhangchen = new person("zhangchen", 23);
var luomi = new person("luomi", 23);
zhangchen.getInfo(); // output My name is zhangchen, and I have 23 years old;
luomi.getInfo(); // output My name is luomi, and I have 23 years old;
luomi.getInfo = function() {
alert("here can rewrite the function of getInfo!");
}
luomi.getInfo(); //here can rewrite the function of getInfo!
zhangchen.getInfo(); // output My name is zhangchen, and I have 23 years old;
从运行结果可以看到,虽然person的每个实例都继承了person.prototype中的方法,但是我们也可以在实例化的对象中重新定义原型对象中的方法,而且也不会影响到其它的实例!
- javascript中面向对象之原型链解析
- Javascript原型,原型链,面向对象
- 《JavaScript》——面向对象之原型
- 《JavaScript》——面向对象之原型
- JavaScript之----面向对象和原型
- JavaScript之面向对象与原型
- JavaScript 面向对象之 原型-prototype
- JavaScript中面向对象与原型
- Javascript 面向对象原型
- JavaScript面向对象-原型
- JavaScript面向对象技术·原型与原型链
- javascript中面向对象中对象,属性,原型链和一些扩展知识总结
- JavaScript原型面向对象构造
- JavaScript面向对象与原型
- Javascript面向对象与原型
- 【JavaScript】面向对象与原型
- JavaScript:面向对象与原型
- JavaScript面向对象与原型
- 多线程(二)
- 想成为优秀的程序员你必须做到的几件事情
- 安卓wifi遥控源代码 ESP8266模块测试
- 在C/C++代码中使用SSE等指令集的指令(5)SSE进行加法运算简单的性能测试
- OOZIE JA017: Unknown hadoop job
- javascript中面向对象之原型链解析
- RDS
- Python标准库的方法
- SSH复习
- (十二)利用processing模拟现实生活中的力
- 欢迎使用CSDN-markdown编辑器
- 指纹、虹膜和人脸之后,身份认证领域的新热点:手背静脉识别
- 二叉树的相关面试题
- VBA教程初级(六):动态声明数组