当JavaScript使用new时发生了什么
2019-07-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