面试中被问到很多原型与对象的东西,于是自己总结了这些东西写下,希望有所收获。
JS创建对象方式
方式一:
在js中并不存在类的概念,所以可以直接通过Object来创建对象.
var person = new Object();
person.name = "maystory";
person.age = 22;
person.say = function() {
alert(this.name+","+this.age);
}
但是使用这种方式创建,带来最大的问题是,由于没有类的约束,无法实现对象的重复利用,并且没有一种约定,在操作时会带来问题。
方式二:
通过Json的方式创建,(json的意思就是javascript simple object notation,json就是js的对象,但是它省去了xml中标签,而是通过{}来完成对象的说明).
- 创建单个对象
var person = {
name:"张三",//通过属性名:属性值来表示,不同的属性通过,来间隔
age:23,
say:function() {
alert(this.name+","+this.age);
}//最后一个属性之后不能有,
}
person.say();
- 创建对象数组
var persons = [
{
name:"Leon",
age:22,
friends:["Ada","Alice"]
},
{
name:"John",
age:33,
friends:["Ada","Chris"]
}
];
方式三:
通过工厂的方式来创建Person对象在createPerson中创建一个对象,然后为这个对象设置相应的属性和方法 ,之后返回这个对象.
function createPerson(name,age) {
var o = new Object();
o.name = name;
o.age = age;
o.say = function() {
alert(this.name+","+this.age);
}
return o;
}
var p1 = createPerson("Leon",22);
var p2 = createPerson("Ada",33);
p1.say();
p2.say();
使用工厂的方式,虽然有效的解决了类的问题,但是依然存在另外一个问题我们无法检测对象p1和p2的数据类型。
方式四:
通过构造函数的方式创建,和基于工厂的创建类似最大的区别就是函数的名称就是类的名称,按照java的约定,第一个字母大写。使用构造函数创建时,在函数内部是通过this关键字来完成属性的定义。
function Person(name,age) {
this.name = name;
this.age = age;
this.say = function() {
alert(this.name+","+this.age);
}
}
使用构造函数创建所带来的第一个问题就是每一个对象中都会存在一个方法的拷贝,如果对象的行为很多的话,空间的占用率就会大大增加。
可以将函数放到全局变量中定义,这样可以让类中的行为指向同一个函数
function Person(name,age) {
this.name = name;
this.age = age;
this.say = say;
}
function say() {
alert(this.name+","+this.age);
}
将行为设置为全局的行为,如果将所有的方法都设计为全局函数的时候,这个函数就可以被window调用,此时就破坏对象的封装性,而且如果某个对象有大 量的方法,就会导致整个代码中充斥着大量的全局函数,这样也将不利于开发。
var p1 = new Person("Leon",22);
var p2 = new Person("Ada",32);
p1.say(); p2.say();
alert(p1 instanceof Person);//true
alert(p1.say==p2.say);//true
方式五:
通过原型的创建方式,使用基于原型的创建可以将属性和方法设置为Person专有的,不能再通过window来调用
function Person(){}
Person.prototype.name = "Leon";
Person.prototype.age = 23;
Person.prototype.say = function() {
alert(this.name+","+this.age);
}
var p1 = new Person();
p1.say();
say();//通过window没有办法调用say方法,如此就完成了封装
至此,所有铺垫结束,原型总算要开始介绍了,下文见。
网友评论