JavaScript 继承与原型链

熟悉 Java,C++ 的人都知道这些语言的继承都是基于 Class 的,但是熟悉 JavaScript 的人也知道 javaScript 是没有Class的(在 ES6 中添加了 Class 关键字,但只是语法,javaScript 仍旧是基于原型的)。

由于 javaScript 的继承只有一种结构,那就是: 对象,每个对象都有指向它的原型(prototype)。这个原型对象又有自己的原型,直到原型为 null 为止;

基于原型链的继承
1. 属性继承
当访问一个对象的属性时,它不仅在该对象上搜索,还会搜寻该对象的原型,以及该对象原型的原型,一次层层向上搜索,直到找到一个名字匹配的属性或者到达原型链的末尾。

var obj = new Object();  // 创建 obj 对象
obj.a = 1;
obj.b = 2; // obj 自身有 a, b 两个属性

obj.[[Prototype]] 有属性 b 和 c ;
//{b: 3, c: 4}

obj.[[Prototype]].[[Prototype]] 是 null
//也就是 {a: 1, b: 2}----> {b: 3, c: 4}---->null

console.log(obj.a); // 1, 访问 obj 自身的属性 a ,属性值为 1
console.log(obj.b); // 2, 访问 obj 自身的属性 b ,属性值为 2
// b 也是 obj 原型的属性,但是它不会被访问到,这种情况叫做“属性遮蔽 (property shadowing)”
console.log(obj.c); // 3, 访问 obj 原型属性 
console.log(obj.d); // undefined ,obj 自身及原型都没有 d 属性,所以是 undefined 

在 ES6 开始[[Prototype]] 可用Object.getPrototypeOf()和Object.setPrototypeOf()访问器来访问

  1. 方法继承
    在 javaScript 中任何函数都可以添加到对象上作为对象的属性,因此,函数的继承与属性的继承没有什么区别。
var obj = {
    a : 2,
    m : function(){
        return this.a + 1;
    }
};

console.log(obj.m()); // 3 ,注意,当调用 obj 的 m() 方法时, this 指向的是 obj 本身。

var p = Object.create(obj);
// p 是一个对象,p 的原型是 obj 
p.a = 12; // 创建 p 自身的属性 
console.log(p.m()); // 13
//注意,当调用 p 的 m() 方法时 this 指向的是 p 本身。
//由于 p 继承了 obj,所以也继承了 obj 的 m() 方法。
//此时的 this.a ,即 p.a 

当对象本身的方法与该对象原型链上的方法重名时,调用该对象的该方法时,访问的是该对象本身的方法,这就像
Java 语言中的方法重写。

你可能感兴趣的:(JavaScript,javascript)