您的位置:首页 > Web前端 > JavaScript

javaScript构造函数分析

2016-04-20 13:50 501 查看
原理:

1.在一个作用域里,申明一个具名函数(构造函数)来模拟基类。这个具名函数的参数作为基类的参数传递。

2.构造函数内部,使用this来为这个函数添加属性和方法。

3.使用的时候,调用这个构造函数并且可以传参。然后使用new关键字改变this的指向,把它指向赋值的变量对象。

<span style="font-size:14px;"><script type="text/javascript">
function Person(name) {
this.name = name;
this.sayname = function() {
console.log(this.name);
}
}
var yy = new Person("yy");
</script></span>


优势和劣势:

优势:

1.可以检测(子类)对象的类型(基类)

<span style="font-size:14px;">   <script type="text/javascript">
function Person(name) {
this.name = name;
this.sayname = function() {
console.log(this.name);
}
}
var yy = new Person("yy");
console.log(yy instanceof Person);  //true
console.log(yy instanceof Object);  //true
console.log(yy.constructor == Person);  //true
console.log(yy.constructor == Object);  //flase
</script></span>


这里,体现了构造函数,基类是可以被侦测到的,yy即是Person的实例,也是Object的实例。这样是非常好的。

yy的构造器是Person这个函数。

2.其他的不赘述了

劣势:

和工厂模式一样,最大的问题就是:在构造函数内声明的方法,同样需要重新实例化一个function,这样每个子类都要重新实例化一遍,显然是性能上不合理的。

当然,可以向下面这样在函数外把方法申明好,然后构造函数内去指向调用,也是可以的,但封装性就大打折扣。

<script type="text/javascript">
var sayName = function() {
console.log(this.name);
}

function Person(name) {
this.name = name;
this.sayName = sayName;
}
var yy = new Person("yy");
yy.sayName();
</script>这里就是单独写了一个函数表达式,在一个作用域里实例了一次;然后构造函数Person的sayName方法指向这个表达式;这样实际上就解决了这个很大的问题,实例方法只被申明了一次。
但是这个解决方案的封装性不好。所以,为了解决这个问题,提出了原型链的方法。

细节:

1.构造函数中this的指向问题:

构造函数实际也是一个普通函数,本质上是将一个匿名函数赋值给了一个变量声明。所以,构造函数在作为普通函数调用的时候。里面的this一般默认是window。

<script type="text/javascript">
function foo() {
var sayName = function() {
console.log(this.name);
}

function Person(name) {
this.name = name;
this.sayName = sayName;
console.log(this); //window
}
Person("YY"); //调用之后,由于this未被改变,所以指向window;
sayName(); //YY
// window被自动添加了name和sayName的属性和方法
}
foo(); //当这个foo()被调用后,上述被验证了
</script>

2.new关键字能改变this的指向,这个我认为干脆所有的构造函数方法建立的对象都使用new关键词,可以规避风险。
<script type="text/javascript">
function Person(name) {
this.name = name;
this.sayName = function() {
console.log(this.name);
}
}
var yy = new Person("yy"); //这个添加了new关键字
yy.sayName(); //this的指向变成了yy,所以变成了yy的方法
var yj = Person("yj"); //注意,这里没用用new关键字
sayName(); //window被自动添加了sayName方法
</script>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息