ECMAScript2017新增两个静态方法
Object.values()
接收一个对象,返回对象值的数组(浅复制)
Object.entries()
接收一个对象,返回键值对数组(浅复制)。非字符串属性会被转换为字符串输出,
符号属性会被忽略
let k1 = Symbol('k1') let o = { a: 1, b: 2, c() { }, [k1]: 3 } console.log(Object.values(o)) //[1,2,fn] console.log(Object.entries(o)) //[['a',1],['b',2],['c',fn]]
原型的语法
之前每次给原型上增加属性都要通过Person.prototype.key=value
function Person() { } //错误的写法1,会丢失constructor属性 Person.prototype = { name: '小红', age: 10 } const p1 = new Person() console.log(Person.prototype.constructor) //ƒ Object() { [native code] } //错误的写法2,这样会得到一个[[Enumberable]]为true的constructor属性 Person.prototype = { constructor: Person, name: '小红', age: 10 } const p1 = new Person() console.log(p1.constructor) for (let k in p1) { console.log(k) //name,age,constructor } //正确的写法 Person.prototype = { name: '小红', age: 10 } Object.defineProperty(Person.prototype, 'constructor', { value: Person, enumerable: false }) const p1 = new Person() for (let k in p1) { console.log(k) //name,age }
实例只有指向原型的指针,没有指向构造函数的指针.
重写构造函数上的原型之后在创建的实例才会引用引得原型。而再次之前创建的实例仍然会引用最初的原型
//例1 let p1 = new Num() function Num() { } Num.prototype.count = 2 console.log(p1.count) //2 //例2 let p1 = new Num() function Num() { } Num.prototype = { constructor: Num, count: 2 } let p2 = new Num() console.log(p1.count) //undefined console.log(p2.count) //2
toString()
方法可把一个 Number 对象转换为一个字符串,并返回结果。
一个参数:可以返回2~32进制的字符串
检查数据类型
Object.prototype.toString.call()
继承
原型链继承的问题
主要问题出现在原型中包含引用值的时候(相同引用)
子类型在实例化时不能给父类型的构造函数传参
盗用构造函数(也叫“经典继承”或“对象伪装”)
使用apply()和call()方法以新创建的对象为上下文执行构造函数
缺点不能访问父类原型上定义的方法
function Animal(color) { this.color = color } function Dog(red, name) { Animal.call(this, red) this.name = name } const d1 = new Dog('红色', '小黄') console.log(d1)
组合继承
就是综合了原型链和盗用构造函数,将两者的优点结合。
基本思路就是使用原型链继承原型上的属性和方法,而通过盗用构造函数继承实例属性
调用过程中会执行两次SuperType函数
function SuperType(name) { this.name = name; this.colors = ['red', 'blue', 'green']; } SuperType.prototype.sayName = function () { console.log(this.name); } function SubType(name, age) { // 继承属性 SuperType.call(this, name); this.age = age; } // 继承方法 SubType.prototype = new SuperType() SubType.prototype.sayAge = function () { console.log(this.age); } const instance1 = new SubType('小红', 19) instance1.sayAge() instance1.sayName() console.log(instance1)
寄生式组合继承(效果最佳) (红宝石248页)
只会调用一次SuperType函数