js对象内存模型

Interesting Points

  1. All instances inherit from the prototype object of the function that created them.
  2. Mozilla/Konqueror have an implementation-specific __proto__ property that points to the prototype object of the creator function (the function used to create any instance of that type).
  3. Regardless of the presence/absence of a __proto__ property, the general idea is that all objects use the prototype object pointed to by that objects creator function. This property is part of the Javascript standard and is called prototype. The prototype object, by default, has a constructor property pointing back to the function that it's the prototype for.
  4. The prototype is only used for properties inherited by objects/instances created by that function. The function itself does not use the associated prototype (but since the function itself is an object, it inherits from the prototype of it's creator function, typically the javascript system "Function" object).
    function Foo() { } ; 
    var f1 = new Foo();
    
    Foo.prototype.x = "hello";
    f1.x   //=> hello
    Foo.x //=> undefined
    
    f1 = new Foo();
    
    Foo.prototype.x = "hello";
    f1.x   //=> hello
    Foo.x //=> undefined
    
    
    Note, we use the Foo.prototype to set properties for all objects created by function Foo. We don't say f1.prototype to set properties for f1. This is a very important point to remember.
  5. Default prototype objects can be replaced with another user created object. While doing so, the constructor property must be set manually to replicate what the javascript runtime does behind the scence with the default prototype object.
    function foo() { } ; var f1 = new foo();
    f1.constructor === foo.prototype.constructor === foo  
    //replace the default prototype object
    foo.prototype = new Object();
    //create another instance l
    f1 = new foo();
    //now we have:
    f1.constructor === foo.prototype.constructor === Object
    //so now we say:
    foo.prototype.constructor = foo
    //all is well again
    f1.constructor === foo.prototype.constructor === foo
    f1 = new foo();
    f1.constructor === foo.prototype.constructor === foo  
    //replace the default prototype object
    foo.prototype = new Object();
    //create another instance l
    f1 = new foo();
    //now we have:
    f1.constructor === foo.prototype.constructor === Object
    //so now we say:
    foo.prototype.constructor = foo
    //all is well again
    f1.constructor === foo.prototype.constructor === foo
    
  6. Each prototype object itself is created (by default) with the Object() constructor, hence the prototype has as it's prototype Object.prototype. Therefore all instances regardless of the type ultimately inherit properties from Object.prototype.
  7. All objects automatically read properties in the prototype chain as-if those properties where defined in the object itself.

    Setting the same property via the object shadows/hides the same property in the prototype for that instance.

    function foo() { } 
    f1 = new foo();
    f2 = new foo();
    foo.prototype.x = "hello";
    
    f1.x  => "hello"
    f2.x  => "hello";
    
    f1.x = "goodbye";   //setting f1.x hides foo.prototype.x
    
    f1.x  => "goodbye"  //hides "hello" for f1 only
    f2.x  => "hello"
      
    delete f1.x
    f1.x  => "hello";   //foo.prototype.x is visible again to f1.
    f1 = new foo();
    f2 = new foo();
    foo.prototype.x = "hello";
    
    f1.x  => "hello"
    f2.x  => "hello";
    
    f1.x = "goodbye";   //setting f1.x hides foo.prototype.x
    
    f1.x  => "goodbye"  //hides "hello" for f1 only
    f2.x  => "hello"
      
    delete f1.x
    f1.x  => "hello";   //foo.prototype.x is visible again to f1.
    
    Setting the property directly in the prototype changes it for all instances.
    foo.prototype.x = "goodbye";
    //now
    f1.x  => "goodbye"
    f2.x  => "goodbye";
    
    //now
    f1.x  => "goodbye"
    f2.x  => "goodbye";
    

 

More Interesting points

Viewing/following various arrows in the diagram above, you'll see some interesting relationships in the core javascript language. (Type these code examples in a javascript console if you want to play along).

  1. Function.__proto__ points to Function.prototype. This results in:
    Function.constructor === Function
    That is to say: Function is it's own constructor !
  2. Object instanceof Object == true.

    This is because:
    Object.__proto__.__proto__.constructor == Object

    Note also that unlike Object instanceof ObjectFoo instanceof Foo == false.

    This is because: Foo does not exist as a constructor for it's own prototype chain.

  3. Function.prototype.toString is a built-in method and is distinct from another built-in method: Object.prototype.toString
    f1.toString() finds:
    Object.prototype.toString
    
    We get something like: [object ...]
    .toString() finds:
    Object.prototype.toString
    
    We get something like: [object ...]
    
    Whereas:
    Foo.toString() first finds & uses:
    Function.prototype.toString()
      
    We get something like: [Function foo...]
    
    If we say:
    delete Function.prototype.toString
    Foo.toString()
      
    We get something like: [object ...]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值