开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情
原型的规则
- 每个对象都有一个内置的隐式原型__proto__属性
- 每个函数都有一个显式原型prototype属性
- 通过new操作符创建出来的对象的隐式原型会指向构造函数的显式原型
function Person(){}
var p1 = new Person()
p1.__proto__ == Person.prototype//true
4.constructor 4.1 在创建Person函数的时候,函数Person的原型对象的constructor属性指向Person函数本身 4.2 如果给函数Person的原型对象赋一个新的对象,那么这个对象的constructor指向的是Object 4.3 通过Object.defineProperty()函数将原型对象的constuctor重新指向Person
原型链的定义
我们从一个对象上获取属性,如果在对象本身没有找到,就会到原型上面找,原型是一个对象,该对象又有自己的原型属性,对应一个对象;原型上面没有,就会到原型的原型上面找,直到obj,就形成了原型链
对象
对象的创建
构造函数方法\构造函数+原型方法
代码:
内存图:
构造函数方法弊端:重复创建函数属性
面试的时候被问到:函数放在函数体内和放在函数的原型上有什么区别? 普通的属性放在构造函数里 方法放在构造函数的显式原型,这样批量创建对象的时候才不会重复创建函数,占用内存
对象的继承
继承的作用:将类中相同的代码抽取,放到父类,子类就可以继承自父类
使用原型链继承(面试被问到了)
先创建一个父类的实例对象,再将该对象赋值给父类的原型,就可以实现继承
弊端:
- 直接打印stu对象看不到继承的属性
- 如果属性是引用类型(数组),比如本例中friends属性,就会出现问题
- 不能给Person传递参数
借用构造函数继承
弊端:
- p对象多出一些属性
- Person函数至少被调用2次
原型式继承
- 法1:setPrototypeOf 将传入的对象作为新创建的对象的原型
- 法2:新建函数
- 法3:Object.create()
寄生组合继承
核心代码
类的继承(class)
class只是function的语法糖 class的实例对象的原型也指向class的原型
class要接收参数 要通过构造函数constructor 当new操作符操作一个类的时候会自动调用constructor
放在class Person里的方法就相当于将方法放在函数Person的原型上
类的访问器方法 在get、set属性的时候做拦截操作
类的静态方法 可以直接通过类来调用的方法 Person.randomPerson()
对象的其他方法
- hasOwnProperty方法 判断属性在对象本身
- in 操作符 只要有这个元素就返回in
- A instanceOf B用来检测 B的原型有没有出现在A的原型链上