美文网首页
当JavaScript使用new时发生了什么

当JavaScript使用new时发生了什么

作者: 司超 | 来源:发表于2019-07-19 17:19 被阅读0次

    函数是怎么工作的

    // 普通函数
    function Person(name,sex) {  
        this.name = name;  
        this.sex = sex;  
    }  
    var per = new Person("sdcyst","male");  // 构造函数
    alert("name:"+per.name+"_sex:"+per.sex); //name:sdcyst_sex:male  
    
    Person('Li', 'male'); // 设置了全局变量
    // window.name: 'Li'
    // window.sex: 'male'
    
    var player = { name: 'Wang', sex: 'unknown' };
    var changePerson = Person.bind(player);  // 绑定到一个对象上使用
    changePerson('kaka', 'male')
    

    一. new是干嘛的?

    new操作符用来生成一个新的对象, 它后面必须跟上一个函数(否则, 会抛出TypeError异常), 这个函数就是我们常说的构造函数。

    二. new操作构造函数生成实例的过程

    (1) 首先, 当我们使用new操作符时, js会先创建一个空的对象obj。
    (2) 然后, 构造函数中的this指向该空对象obj。
    (3) 其次, 在构造函数中通过操作this, 来给obj赋予相应的属性。修改obj的__proto__属性使其指向构造函数的prototype对象 (两者是同一个引用,一荣俱荣,一损俱损)。
    (4) 最后, 如果没有return语句,返回这个经过处理的obj。

    var obj  = {};
    obj.__proto__ = Person.prototype;
    Person.call(obj, name, sex);
    

    三. new操作构造函数的注意事项

    (1) 如果构造函数的返回值是一个原始类型(非引用对象, 如字符串), 忽略该return语句, 如:

    function Test1(str) {
        this.a = str;
        return false;
    }
    var myTest = new Test1("test1");
    alert(myTest); // Object
    

    (2) 如果构造函数的返回值是一个引用对象(数组, 对象, 函数等), 那么返回值会覆盖new创建的"空对象", 如:

     var obj = new function() { return new String("code"); };
     alert(obj); // "code"
    

    扩展

    function Person(name,sex) {  
        this.name = name;  
        this.sex = sex;  
    }  
    Person.prototype.age = 12;    
    Person.prototype.print = function() { 
        alert(this.name+"_"+this.sex+"_"+this.age);  // prototype属性方法里的this指代具体的实例
    };  
    
    var p1 = new Person("name1","male"); 
    var p2 = new Person("name2","male");  
    
    p1.print();  //name1_male_12  
    p2.print();  //name2_male_12  
    
    p1.age = 34; // 创建p1实例的age属性,覆盖了__proto__的同名属性
    p1.print();  
    p2.print(); 
    
    Person.prototype.age = 22;  // 改变Person原型的age属性  
    p1.print();  
    p2.print(); 
    
    p1.print = function() {  // 创建p1对象的print方法,覆盖了__proto__的同名属性
        alert("i am p1");  
    }  
    
    p1.print();  
    p2.print();  
    
    Person.prototype.print = function() { / /改变Person原型的print方法  
        alert("new print method!");  
    }  
    
    p1.print();  
    p2.print();  
    

    四. 参考文章

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/new
    http://www.javaeye.com/topic/288808

    相关文章

      网友评论

          本文标题:当JavaScript使用new时发生了什么

          本文链接:https://www.haomeiwen.com/subject/waxzkctx.html