zoukankan      html  css  js  c++  java
  • js 对象细节

    原型和原型链

    在对象自身身上找不到指定属性时,就会到这个对象的原型__proto__上找,原型也是指向一个对象,在这个对象上还找不到对应属性,则继续到原型上来找...以上过程形成原型链。

    访问对象的原型:obj.__proto__ 或者可以调用Object.getPrototypeOf(obj),返回的值也是obj.__proto__;

    obj.__proto__ 的值,在对象构造的时候,默认等于 obj.constructor.prototype ,可以理解为默认情况下:obj.__proto__ = obj.constructor.prototype = xx。

    所以在对象被构造出来后,再去修改obj.constructor.prototype是无效的,对于已经生成的对象,修改其原型,只能通过修改obj.__proto__来实现。

    空对象{} 的构造函数为 Object

    直接在空对象的原型上添加或修改属性,会作用到js的所有对象中,因为所有的js对象的原型链终点都是Object.prototype所指向的对象:

    Object.getPrototypeOf({}).x=13;
    console.log([].x)    //13

    对象属性

    以下方式添加的属性都是添加到对象身上。

    var obj;
    obj = {
      x:123,
        method(){
          return 123
        }
    };
    obj.y = 99;
    
    // function Person(){
    //     this.a = 123;
    // }
    //
    // obj = new Person();
    console.log(obj)

    包括Object.assign(target,src1,src2),仅仅把src对象身上的属性添加到target身上而已。可以使用assign来实现对象浅拷贝。

    对象的遍历:http://es6.ruanyifeng.com/#docs/object#属性的可枚举性和遍历 

    获取不存在的属性,会从原型上获取,但是创建和原型上名字相同的属性时,对象身上以及原型上会同时存在同名的属性,两者不会冲突,取值的时候会优先从对象身上获取

    var a = {
        name:"ben"
    };
    
    var b = {};
    b.__proto__ = a;
    console.log(b.name); // ben
    
    b.name = 'kity';
    console.log(b.name); // kity
    console.log(a.name); // ben

    对于 ES6 的class ,方法直接定义在原型上

    class Point {
      toString() {
        // ...
      }
    }
    // 等同于
    Point.prototype = {
      toString() {},
    };
    
    typeof Point // "function"

    克隆

    首先复制原型,后复制对象身上的属性。

    function clone(origin) {
      let originProto = Object.getPrototypeOf(origin);
      return Object.assign(Object.create(originProto), origin);
    }

    ps:

    Object.create(target)   的作用实际上以target为原型(__proto__),创建并返回一个空对象。

    继承

      ES5中需要手动修改原型链来实现继承

      ES6中使用extend语法实现继承,本质是首先生成一个父类的对象(在子类的构造函数中必须显式或隐式调用了父类的构造函数),然后以这个父类的对象为原型(__proto__),创建子类对象。

      B继承A,创建B对象,创建的过程是这样的:创建A对象Aobj,Aobj是一个空的对象,接着A的原型Apro,Apro也是空的对象,然后将class A中的方法定义到Apro对象上,接着让Aobj.__proto__ = Apro。这是创建单个class实例的过程。接着创建Bobj,是一个空的对象,然后让Bobj.__proto__ = Aobj,接着让class B上的方法,添加到Aobj对象上。

     

      通过class new出来的对象的constructor指向class,在ES5也是类似,通过函数new出来的对象的constructor指向函数

    Object.freeze 和 const

    const代表属性的值不能发生变化,如果值是对象,则对象可变,但被修饰为const的对象引用不能发生变化

    freeze:浅冻结,被冻结的对象,不能添加、删除、修改属性,但如果属性是对象,则对象可变,在严格模式下,违反freeze的规则会抛出异常,普通模式下则不会有任何变化(静默模式)

  • 相关阅读:
    [GDOI2018]滑稽子图
    单位根反演学习笔记
    ODOO/OPENERP的网页模块QWEB简述
    odoo中的QWeb模板引擎
    项目管理)沟通管理
    从vc6升级到vc7的一些问题及解决方法
    vc++ 2005 发布程序
    颜色取反
    几个VC6.0到VC9.0的错误解决方案
    测试计划测试用例
  • 原文地址:https://www.cnblogs.com/hellohello/p/7920414.html
Copyright © 2011-2022 走看看