Javascript面向对象-创建对象
1、通过”字面量“方式创建(推荐)
var obj = { }; //创建一个空对象 var arr=[]; //创建一个空数组对象
创建语法
var p1={ "true name":"Lily", 'age':18, nationality:"China", run:function () { console.log('Lily is running'); } };
在对象p1中,用{}包裹一个对象,大括号中使用逗号分隔每组属性:属性值。
- 关于属性名:
- 用字面量来创建对象的时候,对象中的属性名可以用单引号或双引号来包裹,也可以忽略引号;
- 当property中出现空格、斜杠等特殊字符,或者与JS关键词冲突时,则必须使用引号;
- 若属性名包含了空格、-(横杠)等,属性访问方式只能采用’[ ]'中括号访问,而不能用对象.属性名的方式;
- 关于属性值:属性的值可以是基本类型,也可以是引用类型,当属性值是一个函数的时候,我们可以称之为方法。对应的属性称之为方法名。
- 分隔多个属性:在一个属性定义之后用逗号分隔,最后一个属性不需要。
2、使用new操作符后跟Object构造函数
var obj = new Object();
Object构造函数
这里Object是构造函数,之前我们说了构造函数也是对象也是所谓的类,Object是所有JavaScript对象的基类。
instanceof运算符可以在继承关系中用来判断一个实例是否属于它的父类型,下面的代码可以看出所谓的基类是什么意思,我们可以理解为Object对象是Javascript对象的共同祖先。
console.log('123' instanceof Object); //false console.log(1 instanceof Object); //false console.log(null instanceof Object); //false console.log([1] instanceof Object); //true console.log({} instanceof Object); //true var Spanner= function (material) { this.material= material; } var s1 = new Spanner("Fe"); console.log(s1 instanceof Spanner); //true console.log(s1 instanceof Object); //true console.log(Spanner instanceof Object); //true
现在用此方法创建一个对象,实际上发生了什么?
var o1=new Object();
和所有的构造函数一样,js解释器做了这些
var o1= {}; //1 首先创建一个新的临时对象 o1._proto_ = Object.prototype; //2 引用构造函数的原型对象 Object.call(o1); //在新对象o1的作用域中执行构造函数Object,也就是将o1赋给this。
创建方法
//使用Object构造函数创建一个对象 var p1 = new Object(); p1.trueName="Lily"; p1.age=18; //使用字面量创建一个对象 var p2= { "trueName": "Lily", 'age': 18 }
实际上,不推荐这个方法来创建一个对象,因为这个方法与前面的字面量方式创建对象效果基本等价,而字面量方式代码更简洁,更因为字面量方式不会调用构造函数本身,效率更高。
PS:在控制台中我们观察到p1和p2看起来是一模一样的,但是除了他们都来自己共同的祖先Object这个共同点之外,没什么特别的联系。
我们知道客观世界中的事物有着广泛的联系,在javascript世界中,对象之间也有着联系,为对象建立联系,共用属性和方法来解决问题是面向对象编程的重要工作内容。
为了减少代码的冗余,以及让对象之间产生更合理的关系,可以使用下面的方法来创建对象。
3、工厂模式
工厂模式更像是方法2的变形,解决了代码冗余的问题
//工厂模式 var person=function (name,age) { var o=new Object(); o.name=name; o.age=age; return o; } var p1=person('Lily',18); //{name: "Lily", age: 18} var p2=person('Mary',20); //{name: "Mary", age: 20} console.log(p1 instanceof person); //false
通过执行函数person返回结构相似对象,但是客观上对象之间没有联系。
4、构造函数
构造函数前面已经详细讲解过了,是创建对象的推荐方法之一。
//构造函数 var Person=function (name,age) { this.name=name; this.age=age; } var p1=new Person('Lily',18); //Person {name: "Lily", age: 18} var p2=new Person('Mary',20); //Person {name: "Mary", age: 20} console.log(p1 instanceof Person); //true
在这个例子中,我们看到不但减少了冗余代码,而且现在p1和p2一样是属于Person对象的实例对象,如果我们给构造函数Person定义原型对象,那么p1和p2就能继承这些原型,使用共同的属性和方法。
5、原型模式
任何一个函数,作为对象都包含一个属性prototype,通过重写构造函数的prototype属性,客观上就实现了属性的继承。
//原型模式 var Person=function(){}; //重写原型的一种方法 Person.prototype.name='Lily'; Person.prototype.age='18'; //另一种写法 Person.prototype={ constructor:Person, name:'Lily', age:18 } var p1=new Person();
在第二种方法中,因为完全重写了prototype属性,需要手动添加prototype的constructor属性,这样做有个坏处,constructor属性成为可枚举属性,通过for/in语句能够遍历到constructor。
6、组合使用构造函数模式和原型模式(推荐)
在创建对象时推荐使用构造函数和原型模式
var Person=function (name,age) { this.name=name; this.age=age; } Person.prototype.species='human'; var p1=new Person('Lily',18); var p2=new Person('Mary',20); console.log(p1.species); console.log(p2.species);
p1和p2现在有了一个共同的属性即她们的物种都是人类。
7、动态原型模式
上面的方式6是常用的创建对象的方法,如果你有其他面向对象语言的编程经验,也许感觉怪怪的,如果把构造函数看做类,它的封装看起来不伦不类,如上例中,定义了一个构造函数之后,再去改写构造函数的原型,怎么看都不像一个整体,使用动态原型模式令构造函数看起来更像一个整体;从外观上看,动态原型模式对原型的改写被包含在构造函数中了。实际上这种方式是在构造函数第一次实例化的时候对原型进行改写。
//构造函数模式+原型模式 var Spanner= function (material) { this.material= material; } Spanner.prototype.operation=function(){ console.log('扭螺丝'); } var s1=new Spanner('Fe'); var s2=new Spanner('Cu'); //动态原型模式 var Spanner=function (material) { this.material=material; if(typeof this.operation!="function"){ Spanner.prototype.operation=function () { console.log('扭螺丝'); } }; } var s1=new Spanner('Fe'); var s2=new Spanner('Cu');
8、寄生构造函数模式
这种模式的基本思想就是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新建的对象。这个模式,除了使用new操作符并把使用的包装函数叫做构造函数之外,和工厂模式几乎一样。
//工厂模式 var person=function (name,age) { var o=new Object(); o.name=name; o.age=age; o.sayName = function() { console.log(this.name) } return o; } var p1=person('Lily',18); //{name: "Lily", job: 18, sayName: ƒ} console.log(p1 instanceof person); //false //寄生构造函数模式 function Person(name, age) { var o = new Object() o.name = name; o.age= age; o.sayName = function() { console.log(this.name) } return o } var p1 = new Person('Lily', 18); //{name: "Lily", job: 18, sayName: ƒ} console.log(p1 instanceof Person); //false
9、稳妥构造函数模式
和工厂模式、寄生构造函数模式一样,稳妥构造函数模式创建出来的对象与构造函数之间没有什么关系,instanceof操作符对他们没有意义。
稳妥构造函数模式与寄生模式写法类似,但有两点不同:一是创建对象的实例方法不引用this,而是不使用new操作符调用构造函数。
//稳妥构造函数模式 function Person(name, job) { var o = new Object() o.name = name; o.job = job; o.sayName = function() { console.log(o.name) } return o } var p1 = Person('Lily', 18); //{name: "Lily", job: 18, sayName: ƒ} console.log(p1 instanceof Person); //false
- 从面试题学习Javascript——面向对象(创建对象)
- Javascript高级程序设计——面向对象之创建对象
- 面向对象 - javascript创建对象模式总结
- \t\t深入了解javascript的面向对象特性 类和对象的创建 实例化
- JavaScript面向对象(2)——创建对象的工厂模式与构造函数模式
- 《JavaScript》——面向对象之对象的创建
- javascript 面向对象的对象创建与继承
- JavaScript高级程序设计之面向对象的程序设计之创建对象之寄生构造函数模式 第6.2.6讲笔记
- javascript面向对象系列第二篇——创建对象的5种模式
- JavaScript高级程序设计之面向对象的程序设计之创建对象之原型模式 第6.2.3讲笔记
- JavaScript高级程序设计之面向对象的程序设计之创建对象之稳妥构造函数模式 第6.2.7讲笔记
- Javascript面向对象之创建对象
- javascript面向对象(对象的创建以及属性和方法的添加)
- 轻松学习JavaScript十二:JavaScript基于面向对象之创建对象(二)
- JavaScript基础——面向对象的程序设计(一)创建对象的几种方式总结
- JavaScript高级程序设计【面向对象-创建对象2】
- JavaScript中的面向对象(一)——创建自定义对象
- (13)javascript 面向对象 创建对象
- 轻松学习JavaScript十二:JavaScript基于面向对象之创建对象(二)
- JavaScript面向对象的程序设计1(创建对象)