一,原型链的基础知识
1,每个函数function都有一个prototype,即显式原型(属性)
2,每个实例对象都有一个–proto–,可称为隐式原型(属性)
原型链:
访问一个对象的属性时,先在自身属性中查找,找到即返回。
如果没有,再沿着–proto–这条链向上查找,找到返回
如果最后没有找到,返回undefined
因为是沿着–proto–这条链查找的,所以原型链实际上是隐式原型链!!
二,早期版本中的类与原型
利用js中的原型链,早期可以实现js中对类的模仿,也就是采用构造函数的形式:
function Fn(){
//构造函数
this.test1=function(){
console.log("test1()")
}
}
Fn.prototype.test2=function(){
console.log("test2()")
} //将方法定义在原型对象上
var fn=new Fn()
fn.test1() //直接在fn中找到了
fn.test2() //fn中没找到,就去原型对象中找,找到了就调用
利用的就是原型链和New的知识。将属性和方法放置在原型链上,实现继承。
三,es6中的类
ES6 中加入了新特性 class,new 跟 function 搭配的怪异行为终于可以退休了,在任何场景,都推荐使用 ES6 的语法来定义类,而令 function 回归原本的函数语义。
类的基本写法:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
// Getter
get area() {
return this.calcArea();
}
// Method
calcArea() {
return this.height * this.width;
}
}
在现有的类语法中,getter/setter 和 method 是兼容性最好的。
我们通过 get/set 关键字来创建 getter,通过括号和大括号来创建方法,数据型成员最好写在构造器里面。
类的写法实际上也是由原型运行时来承载的,逻辑上 JavaScript 认为每个类是有共同原型的一组对象,类中定义的方法和属性则会被写在原型对象之上。
此外,最重要的是,类提供了继承能力。我们来看一下下面的代码。
class Animal {
constructor(name) {
this.name = name;
}
// Getter
get age() {
return this.name+"年纪18";
}
//methods
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
constructor(name) {
//定义实例对象需要传的参数
super(name); //需要用super调用执行父类的构造器函数
}
speak() {
console.log(this.name + ' barks.');
}//狗实例重写覆盖了父类的speak方法
}
let d = new Dog('大黑狗');
d.speak(); // 大黑狗 barks.
console.log(d.age)//大黑狗年纪18
当我们使用类的思想来设计代码时,应该尽量使用 class 来声明类,而不是用旧语法,拿函数来模拟对象。
扫描二维码关注公众号,回复:
13336000 查看本文章