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的规则会抛出异常,普通模式下则不会有任何变化(静默模式)

  • 相关阅读:
    三次请求(读-改-读)引出nibernate 一级缓存
    算法竞赛入门经典第一、二章摘记
    uva 10905 Children's Game
    uva 11205 The broken pedometer
    uva 10160 Servicing stations
    uva 208 Firetruck
    uva 167 The Sultan's Successors
    zoj 1016 Parencodings
    uva 307 Sticks
    uva 216 Getting in Line
  • 原文地址:https://www.cnblogs.com/hellohello/p/7920414.html
Copyright © 2011-2022 走看看