2018-07-12 js函数使用prototype和this是有区别的

  1. js函数中使用this来构造对象
   function Person(name)   //带参数的构造函数 
    { 
        this.name = name;   //将参数值赋给给 this 对象的属性 
        this.SayHello = function() {alert("Hello, I'm " + this.name);};  //给this对象定义一个SayHello方法。  
    }; 
 
    function Employee(name, salary)     //子构造函数 
    { 
        Person.call(this, name);        //将 this传给父构造函数 
        this.salary = salary;       //设置一个 this 的 salary属性 
        this.ShowMeTheMoney = function() {alert(this.name+" $" + this.salary);}; //添加ShowMeTheMoney方法。   

    }; 
     
    var BillGates = new Person("Bill Gates");   //用 Person 构造函数创建 BillGates 对象 
    var SteveJobs = new Employee("Steve Jobs", 1234);   //用 Empolyee构造函数创建 SteveJobs对象 
 
    BillGates.SayHello();   //显示:I'm Bill Gates 
    SteveJobs.SayHello();   //显示:I'm Steve Jobs 
    SteveJobs.ShowMeTheMoney();   //显示:Steve Jobs $1234 
 
    alert(BillGates.constructor == Person);  //显示:true 
    alert(SteveJobs.constructor == Employee);  //显示:true 
     
    alert(BillGates.SayHello == SteveJobs.SayHello); //显示:false
  1. 使用 Person.prototype 来创建原型,结果发现 Employee 对象没有SayHello()方法: 这就是this和prototype的区别。
    当你 反注释掉Person()函数里的 //this.SayHello = function() {alert("Hello, I'm " + this.name);}; 会发现 Employee 对象 总算有 SayHello()方法了!
    或者反注释掉 // Employee.prototype = new Person(); 那么 Employee 对象 SteveJobs调用 SteveJobs.SayHello()时会使用prototype链最终找到SayHello()方法。
       function Person(name)   //基类构造函数 
    { 
        this.name = name;
  //this.SayHello = function() {alert("Hello, I'm " + this.name);};         
    }; 
     
    Person.prototype.SayHello = function()  //给基类构造函数的prototype添加方法 
    { 
        alert("Hello, I'm " + this.name); 
    }; 
     
    function Employee(name, salary) //子类构造函数 
    { 
        Person.call(this, name);    //调用基类构造函数 
        this.salary = salary; 
    }; 
     
   // Employee.prototype = new Person();  //建一个基类的对象作为子类原型的原型,这里很有意思 
     
    Employee.prototype.ShowMeTheMoney = function()  //给子类添构造函数的 prototype添加方法 
    { 
        alert(this.name + " $" + this.salary); 
    }; 
 
    var BillGates = new Person("Bill Gates");   //创建基类 Person 的BillGates 对象 
    var SteveJobs = new Employee("Steve Jobs", 1234);   //创建子类 Employee的 SteveJobs对象 
 
    BillGates.SayHello();       //通过对象直接调用到prototype的方法 
    SteveJobs.SayHello();       //通过子类对象直接调用基类 prototype的方法,关注! 
    SteveJobs.ShowMeTheMoney(); //通过子类对象直接调用子类 prototype的方法 
 
    alert(BillGates.SayHello == SteveJobs.SayHello); //显示:true,表明 prototype的方法是共享的 
 
  1. 在JavaScript内部,对象的属性和方法追溯机制是通过所谓的prototype链来实现的。当用new操作符构造对象时,也会同时将
    构造函数的prototype对象指派给新创建的对象,成为该对象内置的原型对象。
    使用console.dir()打印bill显示其原型是Object,steve的原型则是Person函数!

  2. 并不会因为Employee函数里使用了Person.call(this, name); 就真正有父子类的关系,最多只是父子构造函数——此处并不改变原型,各自原型都还是Object。所以说没有父子类的关系。
    最多只是在Employee的对象的constructor中可以看到Person函数,Employee对象和Person对象的原型其实都是Object。
    只有原型上的关系可以考虑为父子类。

console.dir(BillGates)
VM198:1 Personname: "Bill Gates"__proto__: ObjectSayHello: ()constructor: Person(name)__proto__: Object__defineGetter__: __defineGetter__()__defineSetter__: __defineSetter__()__lookupGetter__: __lookupGetter__()__lookupSetter__: __lookupSetter__()constructor: Object()hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get __proto__: __proto__()set __proto__: __proto__()

console.dir(SteveJobs)
VM199:1 Employeename: "Steve Jobs"salary: 1234__proto__: PersonShowMeTheMoney: ()name: undefined__proto__: ObjectSayHello: ()constructor: Person(name)__proto__: Object
  1. bill和下面的aaa还是有区别的.bill是封装了一层的自定义的Object。而且其SayHello()函数是使用this定义还是使用原型定义,console.dir()看到的当然完全不同了
aaa={}
Object {}
console.dir(aaa)
VM225:1 Object__proto__: Object__defineGetter__: __defineGetter__()__defineSetter__: __defineSetter__()__lookupGetter__: __lookupGetter__()__lookupSetter__: __lookupSetter__()constructor: Object()hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get __proto__: __proto__()set __proto__: __proto__()

console.dir(BillGates)
VM254:1 PersonSayHello: ()name: "Bill Gates"__proto__: Objectconstructor: Person(name)__proto__: Object__defineGetter__: __defineGetter__()__defineSetter__: __defineSetter__()__lookupGetter__: __lookupGetter__()__lookupSetter__: __lookupSetter__()constructor: Object()hasOwnProperty: hasOwnProperty()isPrototypeOf: isPrototypeOf()propertyIsEnumerable: propertyIsEnumerable()toLocaleString: toLocaleString()toString: toString()valueOf: valueOf()get __proto__: __proto__()set __proto__: __proto__()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容