原型链
当我们访问一个对象的属性时,现在该对象上找有没有该属性,没有的话在对象的原型上找,再在原型的原型上找,一层一层在原型链上查找,直到找到匹配的属性或者到达原型链的末尾。特别的,当访问一个不存在的属性时,会遍历整个原型链。
如果只想判断对象本身是否具有某个属性,可以使用对象原型上的内置方法Object.prototype.hasOwnProperty()来判断,这个方法不会访问原型链。
null没有原型,null是原型链的末尾。
每个对象有prototype原型属性,可以通过该属性在对象的原型上定义属性:
let f = function () {
this.a = 1
this.b = 2
}
let o = new f()
f.prototype.b = 3
f.prototype.c = 4
console.log(o.a) //1
// 原型上也有一个b属性,但不会访问到它——属性遮蔽
console.log(o.b) //2
console.log(o.c) //4
console.log(o.d) //undefined
属性遮蔽:如果对象和对象原型上有同一属性,当我们访问该属性只会访问到该对象的属性,不会访问到对象原型上的属性,也可以理解为就近访问
每个函数拥有prototype属性,可以为函数添加原型属性;可以通过new关键字为函数创建实例对象,也可以为实例对象添加属性:
function person() {}
person.prototype.username = 'zhangsan'
var student = new person()
student.address = 'beijing'
console.log(person.name) // person
console.log(person.username) // undefined
console.log(person.prototype.username) // zhangsan
console.log(person.address) // undefined
console.log(person.prototype.address) // undefined
console.log(student.username) // zhangsan
console.log(student.address) // beijing
console.log(person.prototype) // { username: 'zhangsan' }
console.log(student.prototype) // undefined
console.log(Object.getPrototypeOf(person)) // {}
console.log(Object.getPrototypeOf(student)) // { username: 'zhangsan' }
1、对象实例可以访问对象原型上的属性
2、对象无法访问对象实例上的属性
3、使用new关键字创建实例对象时,该实例对象也继承了类原型上的属性
4、通过prototype属性获取类原型上的属性,通过getPrototypeOf()获取实例对象原型上的属性
继承
js中的构造器函数:普通函数可能仅仅包含实现某个功能的代码,构造器本质也是函数,但与普通函数不同的是构造器函数有其自己的属性和方法。可以使用构造器函数定义一个类,通过new这个类得到多个对象实例。
当引入了class、constructor、static、extends、super关键字后,可以更好的以语义化的方式定义类:
1、class:声明一个类
2、constructor:类的构造器函数,在构造器函数中声明类属性
3、static:静态的,声明静态方法,静态方法只能被类调用,不能被类的实例对象调用
4、extends:表示类之间继承的关键词,extends和super搭配使用,继承之后子类的实例对象可以使用父类的属性和非静态方法
5、super():指明子类继承了父类哪些属性
'use strict'
class Polygon {
constructor(height, width) {
this.height = height
this.width = width
}
static fnc() {
return '静态方法'
}
fnc2() {
return 'Polygon的方法'
}
}
class Square extends Polygon {
constructor(sideLength, height, width) {
super(height, width)
this.sideLength = sideLength
}
get area() {
return this.height * this.width
}
set sideLength(newLength) {
this.height = newLength
this.width = newLength
}
}
var square = new Square(2)
console.log(square) //Square { height: 2, width: 2 }
square.sideLength = 9
console.log(square.area) // 81
console.log(square.fnc2()) // Polygon的方法
var polygon = new Polygon(4, 6)
console.log(polygon) // Polygon { height: 4, width: 6 }
console.log(Polygon.fnc()) // 静态方法