zoukankan      html  css  js  c++  java
  • [js高手之路]构造函数的基本特性与优缺点

    上文,通过基本的对象创建问题了解了构造函数,本文,我们接着上文继续了解构造函数的基本特性,以及优缺点.

    每个对象上面都有一个constructor属性( 严格意义上来说,是原型上的,对象是通过查找到原型找到 constructor属性 ).后面讲到原型的时候,我会用示意图的方式说明

     1         function CreateObj(uName) {
     2             this.userName = uName;
     3             this.showUserName = function () {
     4                 return this.userName;
     5             }
     6         }
     7         var obj1 = new CreateObj('ghostwu');
     8         var obj2 = new CreateObj('卫庄');
     9         console.log( obj1.constructor === CreateObj ); //true
    10         console.log( obj2.constructor === CreateObj ); //true

    默认情况下,对象的constructor等于实例化对象的构造函数, constructor最初的作用是用来标识对象的,但是并不是特别准确,因为constructor能被修改,

    识别对象一般用instanceof关键字.

    什么是instanceof?

    要理解这个关键字,需要搞清楚原型链,这里,我提前把他放出来

    //假设instanceof运算符左边是L,右边是R
    L instanceof R 
    //instanceof运算时,通过判断L的原型链上是否存在R.prototype
    L.__proto__.__proto__ ..... === R.prototype ?
    //如果存在返回true 否则返回false

    注意:instanceof运算时会递归查找L的原型链,即L.__proto__.__proto__.__proto__.__proto__...直到找到了或者找到顶层为止。

    所以一句话理解instanceof的运算规则为:

    instanceof检测左侧的__proto__原型链上,是否存在右侧的prototype原型。

            console.log( obj1 instanceof Object ); //true
            console.log( obj2 instanceof Object ); //true
            console.log( obj1 instanceof CreateObj ); //true
            console.log( obj2 instanceof CreateObj ); //true

    obj1,obj2之所以是Object的实例,因为所有对象继承自Object

    借用构造函数

    一个空对象,可以借用现有的构造函数,完成属性和方法的复制

     1         function CreateObj(uName) {
     2             this.userName = uName;
     3             this.showUserName = function () {
     4                 return this.userName;
     5             }
     6         }
     7         var obj = new Object();
     8         CreateObj.call( obj, 'ghostwu' );
     9         console.log( obj.userName ); //ghostwu
    10         console.log( obj.showUserName() ); //ghostwu

    构造函数的优点与缺点

    优点就是能够通过instanceof识别对象,缺点是每次实例化一个对象,都会把属性和方法复制一遍

    1         var obj1 = new CreateObj('ghostwu');
    2         var obj2 = new CreateObj('卫庄');
    3 
    4         console.log( obj1.showUserName === obj2.showUserName ); //false

    从以上执行结果,可以看出obj1.showUserName和obj.showUserName不是同一个【在js中,引用类型比较的是地址, 函数是一种引用类型】,而是存在两个不同
    的内存地址,因为每个对象的属性是不一样的,这个没有什么问题,但是方法执行的都是一样的代码,所以没有必要复制,存在多份,浪费内存.这就是缺点

    怎么解决构造函数的方法复制多次的问题?

     1         function CreateObj(uName) {
     2             this.userName = uName;
     3             this.showUserName = showUserName;
     4         }
     5         function showUserName (){
     6             return this.userName;
     7         }
     8         var obj1 = new CreateObj('ghostwu');
     9         var obj2 = new CreateObj('卫庄');
    10         console.log( obj1.showUserName === obj2.showUserName ); //true

    把对象的方法指向同一个全局函数showUserName, 虽然解决了多次复制问题,但是全局函数非常容易被覆盖,也就是大家经常说的污染全局变量.

    比较好的解决方案?

    通过原型(prototype)对象,把方法写在构造函数的原型对象上

    1         function CreateObj(uName) {
    2             this.userName = uName;
    3         }
    4         CreateObj.prototype.showUserName = function(){
    5             return this.userName;
    6         }
    7         var obj1 = new CreateObj('ghostwu');
    8         var obj2 = new CreateObj('卫庄');
    9         console.log( obj1.showUserName === obj2.showUserName ); //true

    什么是原型对象,以及原型链?且听下回分解

  • 相关阅读:
    CodeForces 706C Hard problem
    CodeForces 706A Beru-taxi
    CodeForces 706B Interesting drink
    CodeForces 706E Working routine
    CodeForces 706D Vasiliy's Multiset
    CodeForces 703B Mishka and trip
    CodeForces 703C Chris and Road
    POJ 1835 宇航员
    HDU 4907 Task schedule
    HDU 4911 Inversion
  • 原文地址:https://www.cnblogs.com/ghostwu/p/7434609.html
Copyright © 2011-2022 走看看