继承与原型链
对于使用过基于类的语言 (如 Java 或 C++) 的开发人员来说,JavaScript 有点令人困惑,因为它是动态的,并且本身不提供一个 class
实现。(在 ES2015/ES6 中引入了 class
关键字,但那只是语法糖,JavaScript 仍然是基于原型的)。
class Point {
constructor(x, y) {
this.x = x;
this.y = y;
}
toString() {
return '(' + this.x + ', ' + this.y + ')';
}
}
// 上面的写法和下面的写法等价
function Point(x, y) {
this.x = x;
this.y = y;
}
Point.prototype.toString = function () {
return '(' + this.x + ', ' + this.y + ')';
};
var p = new Point(1, 2);
当谈到继承时,JavaScript 只有一种结构:对象。每个实例对象( object )都有一个链接指向它构造函数的原型对象(prototype)。该原型对象也有一个自己的原型对象,层层向上直到一个对象的原型对象为 null
。根据定义,null
没有原型,并作为这个原型链中的最后一个环节。
几乎所有 JavaScript 中的对象都是位于原型链顶端的 Object
的实例。
获取原型
-
Object.getPrototypeOf()
返回实例的原型 -
.prototype
返回类型的原型 -
.__proto__
属于非标准实现。在ES5之前没有标准的方法访问这个prototype
,但是大多数浏览器都支持通过__proto__
来访问。ES5 中有了对于这个内置属性标准的 Get 方法Object.getPrototypeOf()
.
let a, a1 = {}
Object.getPrototypeOf(a)
Object.getPrototypeOf(a) === Object.getPrototypeOf(a1)
// true
Object.getPrototypeOf(a) === Object
// ?
Object.getPrototypeOf(a) === Object.prototype
// ?
// =====================================
var a = {a: 1};
// ?
// Object.create()方法创建一个新对象,使用现有的对象作为新创建的对象的原型。
var b = Object.create(a);
console.log(b.a);
var c = Object.create(b);
var b = ['yo', 'whadup', '?'];
// ?
函数
在JavaScript中,每个函数其实都是一个Function
对象。
如果一个函数中没有使用return语句,则它默认返回undefined
。要想返回一个特定的值,则函数必须使用 return
语句来指定一个要返回的值。(使用new关键字调用一个构造函数除外)。
let b = function(){}
b.prototype? Object.getPrototypeOf(b)?
Object.getPrototypeOf(b) === Object.prototype
// ?
b.prototype === Object.prototype
// ?
b.prototype === Function.prototype
//?
Object.getPrototypeOf(
b.prototype = { foo: 1, boo: 2}
// b 和 b.prototype 有什么区别?
原型起源
-
null
; -
Object.prototype
是所有对象的根源,它的原型指向null
; -
Function.prototype
继承自Object.prototype
; -
Function
构造自Function.prototype
; -
Object
构造自Function.prototype
。
Object.prototype
只是挂载在Object
函数对象上
Function.prototype
只是挂载在Function
函数对象上
var o = {a: 1};
// o ---> Object.prototype ---> null
function f() {
return 2;
}
// f ---> Function.prototype ---> Object.prototype ---> null
var b = ['yo', 'whadup', '?'];
// b ---> Array.prototype ---> Object.prototype ---> null
var a = {a: 1};
// a ---> Object.prototype ---> null
var b = Object.create(a);
// b ---> a ---> Object.prototype ---> null
console.log(b.a); // 1
var c = Object.create(b);
// c ---> b ---> a ---> Object.prototype ---> null