前端

Object属性从入门到放弃

2021-04-26  本文已影响0人  Jabo

Object.prototype.constructor

此属性的值是对函数本身的引用,而不是一个包含函数名称的字符串。对原始类型来说,如1,true和"test",该值只可读。

var o = {};
o.constructor === Object; // true

var o = new Object;
o.constructor === Object; // true

var a = [];
a.constructor === Array; // true

var a = new Array;
a.constructor === Array // true

var n = new Number(3);
n.constructor === Number; // true

调试

Object.create()

方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__ 参考
语法:Object.create(proto,[propertiesObject])

const Person = {
    isHuman: false,
    // printIntro:()=>{  // this指向的问题,这里不能用箭头函数
    //  console.log(`My name is ${this.name}, Am I human? ${this.isHuman}`)
    // },
    printIntro:function(){
        console.log(`My name is ${this.name}, Am I human? ${this.isHuman}`)
    }
}

const me = Object.create(Person)

me.name = 'Jabo'
me.isHuman = true

me.printIntro();  // My name is Jabo, Am I human? true
普通函数this指向:

1、普通函数中的this指向它的直接调用者,在默认情况下,this值的是window
2、在严格模式下,没有直接调用者的函数中的this是undefined
3、call、apply、bind绑定this指向

箭头函数

1、箭头函数没有自己的this,它的this是继承而来,默认指向定义它时所处的对象,而不是执行时的对象

/**
 * object.create实现类继承
 */

// Shape - 父类(superclass)
function Shape() {
    this.x = 0;
    this.y = 0;
}

// 父类的方法
Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info('Shape moved!')
}

// Rectangle 子类
function Rectangle(){
    Shape.call(this)  // call super constructor
}

// 子类继承父类
Rectangle.prototype = Object.create(Shape.prototype)
// Rectangle.prototype = Shape.prototype;  // 这里为啥不能使用这种方式呢?【由于子类原型和父类原型指向同一个对象,我们对子类原型的操作会影响到父类原型】
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();
console.log(rect instanceof Rectangle)  // true
console.log(rect instanceof Shape)  // true
rect.move(1, 2)
/**
 * object.create实现类多继承
 */

// Shape - 父类(superclass)
function Shape() {
    this.x = 0;
    this.y = 0;
}

// 父类的方法
Shape.prototype.move = function(x, y) {
    this.x += x;
    this.y += y;
    console.info('Shape moved!')
}


// 父类2
function Area() {
    this.a = 0;
    this.b = 0;
}

// 父类2的方法
Area.prototype.getArea = function(a, b){
    this.a = a;
    this.b = b;
    return this.a * this.b
}


// Rectangle 子类
function Rectangle(type){
    this.type = type
    Shape.call(this)  // call super constructor
    Area.call(this)
}

// 子类继承父类
Rectangle.prototype = Object.create(Shape.prototype)
// Rectangle.prototype = Shape.prototype // 这里为啥不能使用这种方式呢?【由于子类原型和父类原型指向同一个对象,我们对子类原型的操作会影响到父类原型】

// 混合其他
Object.assign(Rectangle.prototype, Area.prototype)
Rectangle.prototype.constructor = Rectangle;


Rectangle.prototype.brief = function() {
    console.log('我是:', this.type)
}

var rect = new Rectangle('长方形');
console.log(rect instanceof Rectangle)  // true
console.log(rect instanceof Shape)  // true
rect.brief()
rect.move(1, 2)
rect.move(3, 4)
console.log('my area:', rect.getArea(4, 6)) // my area: 24
console.log(rect) // Rectangle { x: 4, y: 6, a: 4, b: 6 }

/**
 * 使用 Object.create 的 propertyObject参数
 * */ 

var o;

// 创建一个原型为null的空对象
o = Object.create(null)

o = {};
// 以字面量方式创建的空对象就想到与
o = Object.create(Object.prototype)

o = Object.create(Object.prototype, {
    // foo 会成为所创建对象的数据属性
    foo: {
        writable: true,
        configurable: true,
        value: 'Hello'
    },
    // bar 会成为所创建对象的访问器属性
    bar: {
        configurable: false,
        get: function() {
            return 'get'
        },
        set: function(value) {
            console.log("Setting `o.bar` to", value)
        }
    }
})

o.bar // get

function Constructor(){}
o = new Constructor();
// 等价于: 当然,如果在Constructor函数中有一些初始化代码,Object.create不能执行那些代码
o = Object.create(Constructor.prototype)

// 创建一个以另一个空对象为原型,且拥有一个属性p的对象
// 省略的属性特效默认为false
o = Object.create({}, {p: {value: 10}})
o.p = 12
console.log(o.p) // 10

o.q = 13
for (var prop in o) {
    console.log(prop) //"q"
}


delete o.p  // false

// 创建一个可写的,可枚举的,可配置的属性p
o = Object.create({}, {
    p: {
        value: 20,
        writable: true,
        enumerable: true,
        configurable: true
    }
})

Object.assign()

方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象参考
语法:Object.assign(target, ...sources)

/**
 * 继承属性和不可枚举属性是不能拷贝的
 */
const obj = Object.create({foo: 1}, { // foo 是个继承属性
    bar: {
        value: 2   // bar 是个不可枚举属性
    },
    baz: {
        value: 3,
        enumerable: true  // bar 是自身可枚举属性
    }
})

const copy = Object.assign({}, obj)
console.log(copy)  // { baz: 3 }

Object.defineProperties()

直接在一个对象上定义新的属性或修改现有属性,并返回该对象参考
语法: Object.assign(target, ...sources)

/**
 * 直接在一个对象上定义新的属性或修改现有属性,并返回该对象
 * 语法:Object.defineProperties(obj, props)
 */

var obj = {};
Object.defineProperties(obj, {
    'property1': {
        value: '1',
        writable: true
    },
    'property2':{
        value: 2,
        writable:false
    }
})

Object.defineProperty()

直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。参考
语法:Object.defineProperty(obj, prop, descriptor)

/**
 * 直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
 * Object.defineProperty(obj, prop, descriptor)
 */

const object1 = {}

Object.defineProperty(object1, 'property1', {
    value:10,
    writable: false
})

object1.property1 = 8; // throws an error in strict mode

console.log(object1.property1) //42

Object.entries()

返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
参考
语法: Object.entries(obj)

/**
 * 返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
 * Object.entries(obj)
 */
const object1 = {
    a: 'some',
    b: 10
}

for(const [key, value] of Object.entries(object1)) {
    console.log(`${key}: ${value}`)
}

console.log(Object.entries(object1)) // [ [ 'a', 'some' ], [ 'b', 10 ] ]

var map = new Map(Object.entries(object1))
console.log(map) // Map(2) { 'a' => 'some', 'b' => 10 }
console.log(map.get('a'))  // 'some'

var object2 = {}
Object.defineProperties(object2, {
    a: {
        value: 'a1'
    },
    b: {
        value: 'b2',
        enumerable: true
    },
    c: {
        value: 'c1',
        writable: true
    }
})

console.log(Object.entries(object2)) // [ [ 'b', 'b2' ] ]

创作、分享不易。收藏和点赞是最大的支持!

上一篇 下一篇

猜你喜欢

热点阅读