javaScript构造函数分析

来源:互联网 发布:网络骗局大全微信视频 编辑:程序博客网 时间:2024/06/06 18:29

原理:

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>

1 0
原创粉丝点击