• prototype


    在prototype上有一个叫做constructor的属性,Person.prototype.constructor指向Person,当new Person的时候,每个实例会有一个[[prototype]]指向该对象构造函数的prototype,在chrome里面就是__proto__属性可以查看,但这不是标准的方法(ecmascript 6 把它标准化),因此实例和构造函数的prototype是有可接入的直接联系,但是实例和构造函数之间没有建立联系
     
     
    判断一个对象的[[Prototype]]是否指向某个prototype对象:
    alert(Person.prototype.isPrototypeOf(person1));                             //true
    alert(Person.prototype.isPrototypeOf(person2));                            //true
     
    使用Object.getPrototypeOf( Internet Explorer 9+,Firefox 3.5+, Safari 5+, Opera 12+, and Chrome)来取得[[Prototype]]上的值:
    alert(Object.getPrototypeOf(person1) == Person.prototype);                   //true
    alert(Object.getPrototypeOf(person1).name);                                               //”Nicholas”
     
    变量查找就是沿着实例和构造函数原型间的关系来的,首先在实例本身上找有没有需要的属性方法,没有的话就找构造函数原型上有没有。实例上也能访问到constructor属性值
     
     
    当在实例上添加一个属性方法时,只是添加在当前实例上,不会覆盖构造函数原型上的。当你删除时,也是删除这个实例上的:
     
    当实例上有找到属性或方法,就不会再去读取构造函数原型上的了,只有你把这个属性方法delete了,才会读取构造函数原型上的,因此有一个方法hasOwnProperty用来判断一个属性到底在哪,可以用来检测一个属性是否只存在于他的构造函数prototype上(用in来检测只要在实例或者prototype上存在该属性都会返回true):
    function hasPrototypeProperty(object, name){
        return !object.hasOwnProperty(name) && (name in object);
    }
     
    使用for-in循环的时候,也会把返回实例上和构造函数原型上的属性。
     
    创建真正的空对象:
    使用  var  obj  =  Object.create(null);   
    将会创建真正意义上的空对象,原型链上也是空的
    而使用   var  obj =   {};  
    这样obj 的原型将会指向一个位于 Object.prototype  上的对象,继承相应方法
    (The most important thing about the expanded form is that object literals always set the newly created object’s prototype to an object located at Object.prototype.)
     
    在这个构造函数里,name是一个存取器(assessor)属性,用来保存真正的名字,在strict模式里面,如果使用构造函数忘记new会出错,this不会指向全局window对象,this会保持为 undefined:
    function Person(name) {
        Object.defineProperty(this, "name", {
            get: function() {
                return name; 
            },
            set: function(newName) {
                name = newName;
           },
           enumerable: true,
           configurable: true
         });
         this.sayName = function() {
             console.log(this.name);
         };
    }
     
    直接在原型上扩展的方法在所有实例都是可见的(继承了),Person.prototype.sayHi,但是如果重写整个prototype对象,就是新建了一个Object的实例,再把prototype指向新的实例对象,就会隔断构造函数和旧的prototype:
    function Person(){ }
    var friend = new Person();
    Person.prototype = { 
        constructor: Person, 
        name : “Nicholas”, age : 29,
        job : “Software Engineer”, 
        sayName : function () {
            alert(this.name); }
    };
    friend.sayName();             //error   friend实例指向的是旧的Person.prototype,而不是新的,新的实例才是指向新的
     
    同时要注意实例的constructor会消失,因为constructor属性是在prototype对象上的:
    Person.prototype = {
        constructor : Person,                 //  防止指向构造函数的引用失效,  person1.constructor === Person 才会返回true,不过这样添加的是可遍历的,默认是不可遍历的
        sayName : function () {
            console.log( this.name);
        },
        toString : function () {
            return "[Person " + this .name + "]" ;
        }
    };
     
     
    当使用Object.seal() 或者 Object.freeze()的时候,就不能在实例上新增属性方法了,但是可以通过原型对象添加
     
     
    Object.keys()  可以返回可遍历的实例属性:
    function Person(){}
     
    Person.prototype.name = “Nicholas”;
    Person.prototype.age = 29;
    Person.prototype.job = “Software Engineer”;
    Person.prototype.sayName = function(){
     alert(this.name);
    };
    var keys = Object.keys(Person.prototype);
    alert(keys);                                                                     //”name,age,job,sayName”
    var p1 = new Person();
    p1.name = “Rob”;
    p1.age = 31;
    var p1keys = Object.keys(p1);
    alert(p1keys);                                                            //”name,age”
     
     Object.getOwnPropertyNames()可以返回所有实例属性,不管是可遍历还是不可遍历:
    var keys = Object.getOwnPropertyNames(Person.prototype);                                      //”constructor,name,age,job,sayName”                                                                               
  • 相关阅读:
    【力扣】11. 盛最多水的容器
    T-SQL 学习笔记 Chapter 6 子查询、表表达式 和排名函数 (一)
    忽然发现只是虚长了年岁,莫名的伤感。
    Gridview 多重表头 (二)
    那些 Cynthia 教我的事 之 PMSec (三)
    那些 Cynthia 教我的事 之 PMSec (二)
    那些 Cynthia 教我的事 之 PMSec (一)
    Gridview 多重表头 (一)
    项目总结之SSI (一)
    项目总结之MIT (一)
  • 原文地址:https://www.cnblogs.com/chuangweili/p/5165768.html
Copyright © 2020-2023  润新知