• 对于JavaScript对象的prototype和__proto__的理解


    一、Object和Function的关系:

    刚学JavaScript的时候,看书上说JavaScript中万物皆对象,而javascript中的其他对象都是从Object继承而来,包括内置对象。瞬间觉得Object碉堡了!

    后来,又认识了Function,才知道原来Function才是隐藏在幕后的大BOSS,Object只不过是个大师兄。

    Object和Function都是JS自带的函数对象,Function比较牛逼点,因为它是Object的构造函数,而且Object的__proto__属性指向它的prototype,这意味着Object的那点玩意儿还是从它这里继承的。

    Object.constructor === Function; //true
    Object.__proto__ === Function.prototype; //true
    
    Function.prototype.duang = function(str){console.log(str+"真duang啊!")};
    
    Object.duang("你的头发");
    //你的头发真duang啊!

    Object instanceof Function //true

    然而后来我又发现“javascript中的其他对象都是从Object继承而来”这句话其实是错的,准确的说法应该是:“javascript中的其他对象都继承了Object.prototype中的属性和方法

    Function.prototype.duang = function(str){console.log(str+"真duang啊!")};
    Object.duang(
    "你的头发"); var of = {}; of.duang("猫咪");
    // 你的头发真duang啊! //Uncaught TypeError: of.duang is not a function(…)(anonymous function)


    Function.prototype.duang = function(str){console.log(str+"真duang啊!")};
    Object.prototype.duang =
    Function.prototype.duang;

    var of = {};

    of.duang(
    "猫咪"); //猫咪真duang啊!

    二、普通对象和函数对象:

    JavaScript中万物皆对象,但对象之间也是有区别的。分为函数对象和普通对象。

    函数对象可以创建普通对象,普通对象没法创建函数对象,普通对象JS世界中最低级的小喽啰,啥特权也没有。

    凡是通过new Function创建的对象都是函数对象,其他都是普通对象(通常通过Object创建),可以通过typeof来判断。 

    function f1(){};
    typeof f1 //"function"
    
    
    var o1 = new f1();
    typeof o1 //"object"
    
    var o2 = {};
    typeof o2 //"object"


    定义一个函数或函数表达式时,是使用Function方法去创建的,所以创建出来的都是函数对象;
    var f1 = function(){} 或 function f1(){}的创建过程都是:

    var f1 = new Function(); 

    三、原型与各方面的关系:

    原型就是其构造函数的一个普通实例对象。

    对于任何一个普通的函数f1:function f1(){};

    f1.prototype 就是f1的一个实例对象,因为它不是一个函数声明或函数表达式,所以它是通过new它的构造函数创建的,
    是通过Object创建的,所以它是普通对象。

    一个函数的prototype的创建过程如下:

    var temp1 = new f1();
    f1.prototype = temp1;

    但Function的原型不一样,它是一个函数对象,因为它的构造函数是Function,它通过Function创建,所以它是函数对象!
    它的创建过程如下:

    var temp = new Function();
    Function.prototype = temp;

     

    f1.prototype其他关系如下:

    f1.prototype.constractor === f1;
    
    f1.prototype.__proto__ === Object.prototype;
    
    f1.prototype.__proto__.constractor === Object;
    
    f1.prototype.constractor.prototype = f1.prototype;
    
    f1.prototype.__proto__.constructor.prototype === f1.prototype.__proto__ === Object.prototype

     这里需要特别注意的是:

    1、Object.prototype.__proto__ === null;

    2、Object.__proto__ === Function.prototype
    Object是函数对象,是通过new Function()创建,所以Object.__proto__指向 
    Function.prototype。

    3、Function.__proto__ === Function.prototype
    Function 也是对象函数,也是通过new Function()创建,所以 
    Function.__proto__指向Function.prototype。

    自己是由自己创建的,好像不符合逻辑,但仔细想想,现实世界也有些类似,你是 
    怎么来的,你妈生的,你妈怎么来的,你姥姥生的,……类人猿进化来的,那类人 
    猿从哪来,一直追溯下去……,就是无,(NULL生万物)
    正如《道德经》里所说“无,名天地之始”。

    4、Function.prototype.__proto__ === Object.prototype

    其实这一点我也有点困惑,不过也可以试着解释一下。
    Function.prototype是个函数对象,理论上他的__proto__应该指向 
    Function.prototype,就是他自己,自己指向自己,没有意义。
    JS一直强调万物皆对象,函数对象也是对象,给他认个祖宗,指向 
    Object.prototype。Object.prototype.__proto__ === null,保证原型链能够正 
    常结束。

  • 相关阅读:
    无废话WPF系列9: Binding的源
    无废话WPF系列7:WPF布局控件
    无废话WPF系列6:各类控件家族详解
    无废话WPF系列13:路由事件
    无废话WPF系列4: x名称空间
    无废话WPF系列12: 依赖属性和附加属性
    用C++设计一个不能被继承的类
    HMM的介绍及实现
    C语言综合实验3—计算器四则运算
    机器学习基础
  • 原文地址:https://www.cnblogs.com/macliu/p/5551273.html
Copyright © 2020-2023  润新知