构造
构造是在 js 中创建物件(object)的过程, 使用 new 关键字来定义, 构造过程:
- 创建一个空的 js 物件
- 建立此物件与另一物件的关系(设置 constructor)
- 设置此物件
this关键字 - 如果构造方法没有
return, 那么返回this
原型
原型是 js 物件继承的机制, 一个物件被创造出来, 一定是具有其「原型」, 比如说二哈被构造出来, 那么它就具有狗的特性.
二哈 => 狗 => 生物 => null原型分为显示原型(explicit prototype property)与隐式原型(implicit prototype link).
每个函数在创建之后都有一个 prototype 属性, 其值就是此函数的原型.
每个对象都有一个内置的 [[prototype]] 属性, 大多浏览器都支持使用 __proto__ 来访问, 当然也可以使用 Object.getPrototypeOf() 来访问.
构造与原型关系
以二哈为例, 二哈是一个实例, 狗是一个构造器, 需要通过 new 关键字加 Dog 这个构造器才能构造出二哈.
二哈长什么样/有什么功能等都是与狗的原型密切相关.
function Dog(name, age) { this.age = age this.name = name}
var ha = new Dog('ErHa', 1)
> haDog {name: "ErHa", age: 1}构造器:
> ha.constructorƒ Dog(name, age) { this.age = age this.name = name}> Dog.constructorƒ Function() { [native code] }可以看到二哈(ha)的构造器是狗(Dog), 狗的构造器是 Function.
原型:
> ha.prototypeundefined> Dog.prototype{constructor: ƒ}
> ha.__proto__{constructor: ƒ}> Dog.__proto__ƒ () { [native code] }二哈是个实例, 只有隐式原型, 而狗既有显示原型又有隐式原型, 因为它是个构造器, 又是被实例出来的. 可以看出:
ha.__proto__ === Dog.prototypeObject.getPrototypeOf(ha) === Dog.prototype // (same above)js 是门动态语言, 所以可以随意给实例/构造器添加属性:
> ha.foo = 'foo'> Dog.prototype.bar = 'bar'> ha.foo"foo"> ha.bar"bar"> ha instanceof Dogtrue> ha instanceof Objecttrue
> ha.__proto__ === Object.prototypefalse> ha.__proto__ === C.prototypetrue
> ha.constructor.name"Dog"关于 class
class 是 ES6 中基于 js 原型继承链的语法糖, 以上狗的 class 表示如下:
class Dog { constructor(name, age) { this.age = age this.name = name }}
> Dog.constructorƒ Function() { [native code] }普通类型
> var a = 'a'; var b = 2; var c = true;> a.constructorƒ String() { [native code] }> b.constructorƒ Number() { [native code] }> c.constructorƒ Boolean() { [native code] }> a.__proto__String {"", constructor: ƒ, anchor: ƒ, big: ƒ, blink: ƒ, …}> b.__proto__Number {0, constructor: ƒ, toExponential: ƒ, toFixed: ƒ, toPrecision: ƒ, …}> c.__proto__Boolean {false, constructor: ƒ, toString: ƒ, valueOf: ƒ}小问题
Function.prototype.a = 'a'Object.prototype.b = 'b'function Person() {}var p = new Person()console.log(p.a) // undefinedconsole.log(p.b) // b有位群友问:
继承关系不应该是 p - Person - Function - Object 吗,应该都可以打印出来,为什么中间没有 fucntion 了呢 Person.proto===Function.prototype
他错在 p 继承与 Person, 应该是继承与 Person.prototype, 而 Person.prototype 继承与 Object.prototype.
Function 是其他声明函数的构造函数,proto 隐式原型指向其构造函数的显式原型
总结
- 最新
- 最热
- 最早
- 作者