javaScript构造函数分析
2016-04-20 13:50
501 查看
原理:
1.在一个作用域里,申明一个具名函数(构造函数)来模拟基类。这个具名函数的参数作为基类的参数传递。
2.构造函数内部,使用this来为这个函数添加属性和方法。
3.使用的时候,调用这个构造函数并且可以传参。然后使用new关键字改变this的指向,把它指向赋值的变量对象。
优势和劣势:
优势:
1.可以检测(子类)对象的类型(基类)
这里,体现了构造函数,基类是可以被侦测到的,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>
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>
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- Python动态类型的学习---引用的理解
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 最后一次说说闭包
- Ajax
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- Redux系列02:一个炒鸡简单的react+redux例子
- JavaScript 各种遍历方式详解