• JavaScript之Object对象常用属性与方法手册


    MDN Object参考地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object

    简单描述

    Object 构造函数创建一个对象包装器。
    创建对象的方式:可以通过new Object()Object.create()方法,或者使用字面量标记(初始化标记)初始化对象。
    当以非构造函数形式被调用时,Object 等同于 new Object()
    如下:

    var obj = Object({age:28,name:'jack'});
    console.log(obj); //{age: 28, name: "jack"}

    属性

    Object.prototype

    Object.prototype 属性表示 Object 的原型对象。
    Object.prototype 属性的属性特性:

    • writable:true
    • enumerable:false
    • configurable:true

    几乎所有的 JavaScript 对象都是 Object 的实例;一个典型的对象继承了Object.prototype的属性(包括方法),尽管这些属性可能被遮蔽(亦称为覆盖)。但是有时候可能故意创建不具有典型原型链继承的对象,比如通过Object.create(null)创建的对象,或者通过Object.setPrototypeOf方法改变原型链。

    改变Object原型,会通过原型链改变所有对象;除非在原型链中进一步覆盖受这些变化影响的属性和方法。这提供了一个非常强大的、但有潜在危险的机制来覆盖或扩展对象行为。

    [已废弃]Object.prototype.__proto__

    该特性已经从 Web 标准中删除,虽然一些浏览器目前仍然支持它,但也许会在未来的某个时间停止支持,请尽量不要使用该特性。为了更好的支持,建议只使用 Object.getPrototypeOf()

    通过现代浏览器的操作属性的便利性,可以改变一个对象的 [[Prototype]] 属性, 这种行为在每一个JavaScript引擎和浏览器中都是一个非常慢且影响性能的操作,使用这种方式来改变和继承属性是对性能影响非常严重的,并且性能消耗的时间也不是简单的花费在 obj.__proto__ = ... 语句上, 它还会影响到所有继承来自该 [[Prototype]] 的对象,如果你关心性能,你就不应该在一个对象中修改它的 [[Prototype]]。相反, 创建一个新的且可以继承 [[Prototype]] 的对象,推荐使用 Object.create()

    Object.prototype __proto__ 属性是一个访问器属性(一个getter函数和一个setter函数), 暴露了通过它访问的对象的内部[[Prototype]] (一个对象或 null)。
    实例:

    let Circle = function () {};
    Circle.prototype.add = function(num1,num2){
        return num1 + num2;
    }
    let shape = {};
    let circle = new Circle();
     
    // 设置该对象的原型链引用
    // 过时且不推荐使用的。这里只是举个例子,尽量不要在生产环境中这样做。
    shape.__proto__ = circle;
    
    // 判断该对象的原型链引用是否属于circle
    console.log(shape.__proto__ === circle); // true
    
    result = shape.add(1,2);
    console.log(result); //3
    let shape = function () {};
    let p = {
        a: function () {
            console.log('aaa');
        }
    };
    shape.prototype.__proto__ = p;
    
    let circle = new shape();
    circle.a();//aaa
    console.log(shape.prototype === circle.__proto__);//true
    
    //或者
    let shape = function () {};
    var p = {
        a: function () {
            console.log('a');
        }
    };
    
    let circle = new shape();
    circle.__proto__ = p;
    circle.a(); //  a
    console.log(shape.prototype === circle.__proto__);//false
    
    //或者
    function test() {}
    test.prototype.myname = function () {
        console.log('myname');
    }
    let a = new test()
    console.log(a.__proto__ === test.prototype);//true
    a.myname();//myname
    
    //或者
    let fn = function () {};
    fn.prototype.myname = function () {
        console.log('myname');
    }
    
    let obj = {
        __proto__: fn.prototype
    };
    
    obj.myname();//myname

    Object.prototype.constructor

    返回创建实例对象的 Object 构造函数的引用。注意,此属性的值是对函数本身的引用,而不是一个包含函数名称的字符串。对原始类型来说,如1,true和"test",该值只可读。

    所有对象都会从它的原型上继承一个 constructor 属性:

    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

    例子:如下情况,该对象具有创建自身的create方法。

    function Parent() {};
    function CreatedConstructor() {}
    
    CreatedConstructor.prototype = Object.create(Parent.prototype);
    
    CreatedConstructor.prototype.create = function create() {
      return new this.constructor();
    }
    
    new CreatedConstructor().create().create(); // error undefined is not a function since constructor === Parent

    在上面的示例中,将显示异常,因为构造函数链接到Parent。为了避免它,只需分配您将要使用的必要构造函数。

    function Parent() {}; 
    function CreatedConstructor() {} 
    
    CreatedConstructor.prototype = Object.create(Parent.prototype); 
    CreatedConstructor.prototype.constructor = CreatedConstructor; // set right constructor for further using
    
    CreatedConstructor.prototype.create = function create() { 
      return new this.constructor();
    } 
    
    new CreatedConstructor().create().create(); // it's pretty fine

    现在很清楚为什么更改构造函数会很有用,再看下面的例子:

    function ParentWithStatic() {}
    
    ParentWithStatic.startPosition = { x: 0, y:0 };
    ParentWithStatic.getStartPosition = function getStartPosition() {
      return this.startPosition;
    } 
    
    function Child(x, y) {
      this.position = {
        x: x,
        y: y
      };
    }
    
    Child.prototype = Object.create(ParentWithStatic.prototype); 
    Child.prototype.constructor = Child;
    
    Child.prototype.getOffsetByInitialPosition = function getOffsetByInitialPosition() {
      var position = this.position;
      var startPosition = this.constructor.getStartPosition(); // error undefined is not a function, since the constructor is Child
    
      return {
        offsetX: startPosition.x - position.x,
        offsetY: startPosition.y - position.y
      }
    };

    对于此示例,我们需要保持父构造函数继续正常工作。

    方法

    Object.setPrototypeOf()

    Object.setPrototypeOf() 方法设置一个指定的对象的原型 ( 即, 内部[[Prototype]]属性)到另一个对象或 null。
    语法:Object.setPrototypeOf(obj, prototype)
    参数:

    • obj:要设置其原型的对象。
    • prototype:该对象的新原型(一个对象 或 null)。

    如果对象的[[Prototype]]被修改成不可扩展(通过 Object.isExtensible()查看),就会抛出 TypeError异常。如果prototype参数不是一个对象或者null(例如,数字,字符串,boolean,或者 undefined),则什么都不做。否则,该方法将obj的[[Prototype]]修改为新的值。

    Object.setPrototypeOf()是ECMAScript 6最新草案中的方法,相对于 Object.prototype.__proto__ ,它被认为是修改对象原型更合适的方法。

    例如:

    var dict = Object.setPrototypeOf({}, null);

     Polyfill

    使用较旧的 Object.prototype.__proto__ 属性,我们可以很容易地定义Object.setPrototypeOf 如果它不可用:

    // 仅适用于Chrome和FireFox,在IE中不工作:
    Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {
      obj.__proto__ = proto;
      return obj; 
    }

     Object.getPrototypeOf()

    描述:方法返回指定对象的原型(内部[[Prototype]]属性的值)。

    语法:

    Object.getPrototypeOf(object)

    参数:object,要返回其原型的对象。

    返回值:给定对象的原型。如果没有继承属性,则返回 null 。

    实例:

    var proto = {};
    var obj = Object.create(proto);
    console.log(Object.getPrototypeOf(obj) === proto); // true
    
    var reg = /a/;
    console.log(Object.getPrototypeOf(reg) === RegExp.prototype); // true
    
    //Object.getPrototypeOf( Object )是把Object这一构造函数看作对象,
    //返回的当然是函数对象的原型,也就是 Function.prototype。
    console.log(Object.getPrototypeOf(Object)== Function.prototype) //true

    Object.values()

    Object.values()方法返回一个给定对象自身的所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 ( 区别在于 for-in 循环枚举原型链中的属性 )。

    语法:

    Object.values(obj)

    参数:obj,被返回可枚举属性值的对象。

    返回值:一个包含对象自身的所有可枚举属性值的数组。

    var obj = { foo: 'bar', baz: 42 };
    console.log(Object.values(obj)); // ['bar', 42]
    
    // array like object
    var obj = { 0: 'a', 1: 'b', 2: 'c' };
    console.log(Object.values(obj)); // ['a', 'b', 'c']
    
    // array like object with random key ordering
    // when we use numeric keys, the value returned in a numerical order according to the keys
    var an_obj = { 100: 'a', 2: 'b', 7: 'c' };
    console.log(Object.values(an_obj)); // ['b', 'c', 'a']
    
    // getFoo is property which isn't enumerable
    var my_obj = Object.create({}, { getFoo: { value: function() { return this.foo; } } });
    my_obj.foo = 'bar';
    console.log(Object.values(my_obj)); // ['bar']
    
    // non-object argument will be coerced to an object
    console.log(Object.values('foo')); // ['f', 'o', 'o']

    如果要 Object.values兼容不支持它的旧环境,可在 tc39/proposal-object-values-entries 或 es-shims/Object.values 中找到 Polyfill 。根据Object.keys()的Polyfill仿写一个:

    if (!Object.values) Object.values = function(obj) {
        if (obj !== Object(obj))
            throw new TypeError('Object.values called on a non-object');
        var val=[],key;
        for (key in obj) {
            if (Object.prototype.hasOwnProperty.call(obj,key)) {
                val.push(obj[key]);
            }
        }
        return val;
    }
  • 相关阅读:
    Python之面向对象知识整理
    python2与python3的区别
    Gitlab 删除仓库文件夹
    Git撤销本地commit(未push)
    js库
    HTML | 打开网址后3秒跳转外链
    Vue CLI | 安装
    npm | npm淘宝镜像和查看镜像设置
    swiper | 过渡效果 effect: 'fade' 导致文字重叠
    CSS改变背景 | pattern.css
  • 原文地址:https://www.cnblogs.com/moqiutao/p/6927038.html
Copyright © 2020-2023  润新知