浅谈JavaScript对象的创建方式

时间: 作者:所支

  

[javascript,创建对象]浅谈JavaScript对象的创建方式

  

通过Object构造函数或对象字面量创建对象时,使用同一个接口创建很多对象时,会产生大量的重复代码。为了简化,引入了工厂模式。

  

  

工厂模式  

  
  
  function createPerson(name, age, job) {  var obj = new Object();  obj.name = name;  obj.age = age;  obj.job = job;  obj.sayHello(){  alert(this.name);  };  return obj;  }  var p1 = createPerson("xxyh", 19, "programmer");  var p2 = createPerson("zhangsan", 18, "student");
  
  

这种创建对象的方式大大简化了代码,然而也存在不足,那就是无法确定对象的类型。为了解决这个问题,出现下面这种模式。

  

  

构造函数模式  

  

创建自定义的构造函数,从而定义自定义对象类型的属性和方法。

  
  

  
  
  function Person(name, age, job) {  this.name = name;  this.age = age;  this.job = job;  this.sayName = function () {  alert(this.name);  };  }  var p1 = new Person("xxyh", 19, "programmer");  var p2 = new Person("Jack", 18, "student");
  
  

上例中,Person()取代了createPerson(),除此之外,还有几点不同:  

  

?没有显示地创建对象;  
  
  

  

?直接将属性和方法赋值给了this对象  
  
  

  

?没有return语句  

  

创建Person对象,必须使用new操作符。分为4个步骤:  

  

?创建一个新对象  
  
  

  

?将构造函数的作用域赋给新对象  
  
  

  

?执行构造函数中的代码  
  
  

  

?返回新对象  

  

p1和p2分别保存着Person的一个实例。

  

  
  
  alert(p1.constructor == Person);  // true  alert(p2.constructor == Person);  // true
  
  

检测类型时最好使用instanceof:  

  
  
  alert(p1 instanceof Object);  // true  alert(p1 instanceof Person);  // true  alert(p2 instanceof Object);  // true  alert(p2 instanceof Person);  // true
  
  

p1和p2都是Object的实例,因为所有对象均继承自Object。

  

  

2.1将构造函数当作函数  
  
  

  
  
  // 当作构造函数使用  var person = new Person("xxyh", 19, "programmer");  person.sayName();  // "xxyh"  // 当作普通函数  Person("zhangsan", 18, "student");  // 添加到window  window.sayName();  // "zhangsan"  // 在另一个对象的作用域中调用  var obj = new Object();  Person.call(obj, "Jack", 29, "manager");  obj.sayName();  // "Jack",obj拥有了所有属性和方法
  
  

2.2构造函数的问题  

  

使用构造函数的问题,就是每个方法都要在每个实例上重新创建一遍。p1和p2都有一个sayName()方法,但是他们不是一个Function的实例。在JavaScript中,函数时对象,因此每定义一个函数,就实例化了一个对象。

  

  

构造函数也可以这样定义:  
  

  
  
  function Person(name, age, job) {  this.name = name;  this.age = age;  this.job = job;  this.sayName = new Function("alert(this.name)");  }
  
  

因此,不同实例上的同名函数时不相等的:  

  
  
  alert(p1.sayName == p2.sayName);  // false
  
  

然而,创建两个同样功能的Function是多余的,根本不需要在执行代码前就把函数绑定到特定对象上面。

  

  
  
  function Person(name, age, job) {  this.name = name;  this.age = age;  this.job = job;  this.sayName = sayName;  }  function sayName() {  alert(this.name);  }  var p1 = new Person("xxyh", 19, "programmer");  var p2 = new Person("Jack", 18, "student");
  
  

上面将sayName()的定义移到构造函数外部,然后在构造函数内部将属性sayName设置为全局的sayName函数。这样,sayName包含了指向函数的指针,p1和p2共享了全局作用域中定义的同一个sayName()函数。

  

  

但是,这样做又出现了新问题:在全局作用域中定义的函数只能被某个对象调用。而且如果对象定义了很多方法,那么引用类型就失去了封装性。

  

  

原型链模式 (责任编辑:admin)

推荐图片Related

相关文章Related

查看更多热门新闻


首页 | js代码 | jQuery特效 | 其他代码 | 关于我们

Copyright © 2010-2019 菲娱国际平台 版权所有

系统要求:本站自适应各终端浏览器分辨率

请使用Google、Firefox、IE9、百度浏览器登录网站

网站地图 | RSS订阅 | 菲娱国际平台