Inheritance and Prototype in js

When it comes to inheritance, there is only one data type in js: object. Every object has a private property named \_proto___ which points to its prototype. The top of the prototype is Object. Object.__proto__ === null

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 让我们从一个函数里创建一个对象o,它自身拥有属性a和b的:
let f = function () {
this.a = 1;
this.b = 2;
}
/* 这么写也一样
function f() {
this.a = 1;
this.b = 2;
}
*/
let o = new f(); // {a: 1, b: 2}

// 在f函数的原型上定义属性
f.prototype.b = 3;
f.prototype.c = 4;

// 不要在 f 函数的原型上直接定义 f.prototype = {b:3,c:4};这样会直接打破原型链
// o.[[Prototype]] 有属性 b 和 c
// (其实就是 o.__proto__ 或者 o.constructor.prototype)
// o.[[Prototype]].[[Prototype]] 是 Object.prototype.
// 最后o.[[Prototype]].[[Prototype]].[[Prototype]]是null
// 这就是原型链的末尾,即 null,
// 根据定义,null 就是没有 [[Prototype]]。

// 综上,整个原型链如下:

// {a:1, b:2} ---> {b:3, c:4} ---> Object.prototype---> null
1
2
3
4
5
6
function doSomething(){}
console.log( doSomething.prototype );
// 和声明函数的方式无关,
// JavaScript 中的函数永远有一个默认原型属性。
var doSomething = function(){};
console.log( doSomething.prototype );
1
2
3
4
5
6
7
8
9
10
11
12
{
constructor: ƒ doSomething(),
__proto__: {
constructor: ƒ Object(),
hasOwnProperty: ƒ hasOwnProperty(),//return a boolean
isPrototypeOf: ƒ isPrototypeOf(),//return a boolean on whether inherit
propertyIsEnumerable: ƒ propertyIsEnumerable(),//是否可枚举
toLocaleString: ƒ toLocaleString(),//可输出日期等
toString: ƒ toString(),//
valueOf: ƒ valueOf()
}
}

New

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function foo() {}
foo.prototype = {
foo_prop: "foo val"//add a property
}
var proto = new foo //proto.__proto__ = foo.prototype
proto.bar_prop = "bar val"//add a property on proto

function bar() {}
bar.prototype = proto//
var inst = new bar//
console.log(inst.__proto__ === bar.prototype)
console.log(inst.__proto__ === proto)
console.log(bar.prototype === proto)
console.log(proto.__proto__ === foo.prototype)
console.log(proto.__proto__ === foo.prototype)
// inst -> bar.prototype -> proto -> foo.prototype

Object.create

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function foo(){}
foo.prototype = {
foo_prop: "foo val"
};
function bar(){}
var proto = Object.create(
foo.prototype,
{
bar_prop: {
value: "bar val"
}
}
);
bar.prototype = proto;
var inst = new bar;
console.log(inst.foo_prop);//foo val
console.log(inst.bar_prop);//bar val

IE8 unsupported

Object.setPrototypeOf

perform badly

__proto__

need abandoning

prototypeObject.getPrototypeOf

1
2
3
var a1 = new A(); 
var a2 = new A();
Object.getPrototypeOf(a1).doSomething == Object.getPrototypeOf(a2).doSomething == A.prototype.doSomething

Comments