JavaScript原型及原型链
- 第一次写这种技术类的公开笔记,有些思路不知道如何用更好的语言去组织表达清晰,希望看到的各位看官,不喜勿喷,如果有错误的地方,欢迎指正。
JS的类型
- 分为基本类型和引用类型,
- 基本类型:number,string,boolean,undefined,null,bigInt,symbol
- 引用类型:Object
- 基本引用类型
- Date RegExp
- 原始值包装类型 Number String Boolean
- 单例内置对象 Global Math
- 集合引用类型
- Object
- Array
- ArrayBuffer 定型数组
- Map
- WeakMap
- Set
- WeakSet
- ...
- 基本引用类型
对JS来讲,使用最多的当属对象
JS万物可对象
- 创建对象的常见两种方式
- 通过字面量形式
- 通过new操作符
构造函数本身也是Function的一个对象实例, 也可叫做函数对象,
- 函数对象内部有[[call]]、[[constructor]]属性,
- 使用new构造函数,用[[constructor]]属性
- 普通调用时,用[[call]]属性
那使用 new 操作符,通过new操作符调用构造函数会执行什么操作?
- 在内存中创建一个对象
- 这个新对象内部的[[Prototype]]特性被赋值为构造函数的 prototype 属性。
- 构造函数内部的 this 被赋值为这个新对象(即 this 指向新对象)。
- 执行构造函数内部的代码(给新对象添加属性)。
- 如果构造函数返回非空对象,则返回该对象;否则,返回刚创建的新对象。
在上述创建对象过程中,new操作符创建的实例对象上,包含隐式原型属性__proto__, 构造函数对象上有显示原型prototype属性, 实例对象隐式原型属性指向构造函数对象的显示原型prototype。 同理构造函数对象上也有隐式原型属性__proto__,指向Function.prototype,Function原型的尽头是null。 构造函数对象的原型对象上有constructor属性,且指向构造函数对象。
注:ES6中定义了 Object.setPrototypeOf 以及 Object.getPrototypeOf
// 定义Parent构造函数
function Parent(param) {
this.name = "parent";
this.fruits = ["apple","banana"];
this.param = param;
this.getName = function() {
console.log(this.name);
console.log(this.param);
}
}
// 给Parent原型对象上添加方法
Parent.prototype.say = function() {
console.log(this.name + "," + this.param);
}
// 用Parent创建实例p1
let p1 = new Parent("p1 param");
p1.fruits.push("strabrew");
// console.log(p1.fruits);;
p1.getName();
p1.say();
console.log(p1 instanceof Parent); // true
console.log(Parent.prototype instanceof Parent) // false
console.log(p1.__proto__ == Parent.prototype); // true
console.log(p1.__proto__.constructor == Parent); // true;
console.log(Parent.prototype.constructor == Parent); // true;
console.log(Parent.prototype.__proto__ instanceof Parent); // false
console.log(Parent.prototype.__proto__ === Object.prototype); // true
// 对象分:函数对象和普通对象,函数对象只添加prototype属性,函数对象也是对象,也有construcor和__proto__属性
console.log(Parent.constructor == Function); // true
console.log(Parent.__proto__ == Function.prototype); // true
console.log(p1.prototype); // undefined
原型链
ECMA-262 把原型链定义为 ECMAScript 的主要继承方式。其基本思想就是通过原型继承多个引用类型的属性和方法。 原型本身有一个内部指针指向另一个原型,相应地另一个原型也有一个指针指向另一个构造函数。这样就在实例和原型之间构造了一条原型链。这就是原型链的基本构想。