zoukankan      html  css  js  c++  java
  • Object.prototype 原型和原型链

    Object.prototype 原型和原型链

    原型

    Javascript中所有的对象都是Object的实例,并继承Object.prototype的属性和方法,有些属性是隐藏的。换句话说,在对象创建时会存在预定义的属性,其中有一个属性就是原型对象。在函数对象中存在原型对象prototype,在普通对象中没有prototype,但存在__proto__。或者说使用function定义的对象与使用new操作符生成的对象之间有一个重要的区别,这个区别就是function定义的对象有一个prototype属性,使用new生成的对象就没有这个prototype属性,存在__proto__

    var o =new Object();    
    console.log(o.__proto__);
    console.log(o.prototype);//undefined
    
    var fn = function(){} 
    console.log(fn.prototype);//Object {constructor: function}
    var f1 = new fn();
    console.log(f1.__proto__);
    console.log(f1.__proto__===fn.prototype);//true
    
    

    原型链

    那么__proto__是什么?每个对象都会在其内部初始化一个属性,就是__proto__
    普通对象中的__proto__是什么呢? Object的本质函数对象,是通过new Function()创建,所以Object.__proto__指向Function.prototype。同理,Function也是函数对象,因此Function.__proto__同样指向Function.prototypeObject.prototype对象也有__proto__属性,但它比较特殊,为null。这个由__proto__串起来的直到Object.prototype.__proto__为null的链就是原型链。

    console.log(Object.__proto__ === Function.prototype);//true
    console.log(Function.__proto__===Function.prototype);//true
    console.log(Object.prototype.__proto__);//null
    

    当我们访问一个对象的属性 时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样 一直找下去,也就是我们平时所说的原型链的概念。参考下面的例子:

    var Fn = function(){};
    Fn.prototype.Hello = function(){
    		console.log("Hello World");
        }
    var f1 = new Fn();
    f1.Hello();//Hello World
    

    首先var f1=new fn(),f1是Fn的实例,可以得出f1.__proto__=Fn.prototype。当我们调用f1.hello()时,首先f1中没有Hello这个属性,于是,它会到他的__proto__中去找,也就是Fn.prototype,而我们在上面定义了 Fn.prototype.Hello=function(){}; 于是,就找到了对应的方法。
    从一个更复杂的例子中看原型链的原理:

    var Person = function() {};
    Person.prototype.Name = function() {
        console.log("person name");
    }
    Person.prototype.Sex = "male or female";
    
    var Younger = function() {};
    Younger.prototype = new Person();
    Younger.prototype.Age = function() {
        console.log("14-28")
    };
    Younger.prototype.Sex = "female";
    
    var Ann = new Younger();
    Ann.Name(); //person name
    console.log(Ann.Age()); //14-28
    console.log(Ann.Sex); //female
    

    对上述代码,我们可以进行如下分析:
    var Younger = function() {}=>:Younger.__proto__=Person.prototype,
    Younger.prototype = new Person()
    =>:Younger.prototype.__proto__ = Person.prototype,
    var Ann = new Younger()===>Ann.__proto__=Younger.prototype,
    综上可得:
    Ann.__proto__.__proto__ = Person.prototype

    Ann本身没有Name()方法,于是从Ann.__proto__(Younger.prototype)中找,仍没有找到于是在向上一层Ann.__proto__.__proto__(Person.prototype)中寻找,最终在Person.prototype中找到对应的方法并调用。
    同理,Ann本身并没有Age()方法,但在Ann.__proto__(Younger.prototype)存在。
    对于Ann.Sex,在Ann.__proto__(Younger.prototype)中已经能够找到,便不再向上寻找,因此输出是female

  • 相关阅读:
    jvm调试相关:jmap失效下找到alternatives神器
    作业2:java内存模型图示
    Python脚本:Linux自动化执行Python脚本
    Nodejs:单线程为什么能支持高并发?
    作业1:java虚拟机内存模型图示
    SpringBoot中获取spring.profiles.active的值
    线程中使用注解出现空指针如何解决?
    java7:核心技术与最佳实践读书笔记——对象生命周期
    java7:核心技术与最佳实践读书笔记——类加载
    虚拟机上不了网啦
  • 原文地址:https://www.cnblogs.com/Nancy-wang/p/6903221.html
Copyright © 2011-2022 走看看