msdlisper Front-end

Javascript es5 的 Object的原型和继承

2019-11-17

es5原生支持的继承

Object 的 方法

delete

  • delete不能删除原型链上的属性, 但会返回true
  • 不能删除var申明的全局属性
  • 不能删除不可配置的属性, 比如Object.prototype

属性的检测

  • hasOwnProperty() 非原型链
  • propertyIsEnumerable() 非原型链并且可枚举

getter和setter

定义方式:

  • Object.defineProperty
  • 字面量
var p = {
    x: 1,
    y: 2,
    set r (n) {
        return this.x = n
    },
    get r() {
        return this.x*this.y
    }
}
  • new
  • create

Object属性的特性

  • value
  • writable
  • enumerable
  • configurable
  • set
  • get

示例, extend方法, 需要复制对象, 同时别忘了属性的特性

var l = console.log
var a = {x: 1, y: 2}

Object.defineProperties(a, {
    'x': {
        get() {
            return this.r();
        }
    },
    'r': {
        value() {
            return this.y
        }
    }
})

Object.defineProperties(Object.prototype, {
    'extend': {
        value(o) {
            var names = Object.getOwnPropertyNames(o)
            var that = this
            names.map(function(name, index) {
                if (name in that) {
                    return
                }
                var desc = Object.getOwnPropertyDescriptor(o, name)
                Object.defineProperty(that, name, desc)
            })
        },
        writable: true,
        enumerable: false,
        configurable: false
    }
})


var b = {r: 3}
b.extend(a)

Object的方法

  • getOwnPropertyDescriptor
  • getOwnPropertyName 自有属性
  • keys 自有属性并可枚举
  • definedProperty
  • create(B), 创建一个新对象, 以B为原型

Object.prototype的蜜汁方法

  • A.hasOwnProperty
  • A.isPropertotypeOf(B) 检查原型链

    判断B是不是这个对象的原型

    还可以通过 instance, B.constroctor.prototype = A.controctor.prototype

继承

拷贝

类似上面’extend’的实现, es6还有一种实现

Object.create(
  Object.getPrototypeOf(obj), 
  Object.getOwnPropertyDescriptors(obj) 
);

这个可以解决Object.assign没有拷贝set/get的问题

原型链判断

类型判断

  • A.isPropertotypeOf(B)
    • 对象之间的继承关系判断
  • a.constructor === A.prototype.constructor
    • 通过constructor标识来判断类型
  • Object.prototype.toString.call()
    • 判断基本类型
  • instanceOf
    • a instanceOf A 只能判断构造函数

继承的几种方式

  • create方式: 完全替换端父类的某个方法
B.prototype = Object.create(A.prototype)
B.prototype.constructor = B

问: B.prototype = Object.create(A.prototype) 和 B.prototype = new A()的区别在哪儿?

作用其实一样 , create可以接受null

  • 构造函数和方法链: 修改和扩充方法
function B() {
    A.apply(this, arguments)
}
B.prototype = Object.create(A.prototype)
B.prototype.constructor = B
 
B.prototype.add = function() {
    // ...
    A.prototype.add.apply(this, arguments )
}

Comments

Content