转 js中对象和对象创建方法
这一次我们来说一说在JavaScript中经常会用到的一个复杂基本类型,对象,先从对象的属性讲起,再讲对象的创建方法,基本涵盖了创建对象的各种方法,大家一起学习呀~
一、对象
要掌握对象的使用及继承,首先当然需要先理解它,接下来,将会对对象的属性类型进行一个整理
1、什么是对象
对象其实是无序属性的集合,其属性可以包含基本值,对象或者函数,比如像下面这个例子就是一个person对象啦
var person = {};
Object.defineProperty(person, "name", {
writable: false,
value: "Nicholas"
});
console.log(person.name); // Nicholas
// 重新赋值
person.name = "Greg";
console.log(person.name); // Nicholas
从上面的例子我们可以看到,因为设置了person对象的name属性为不可修改,因此无论你在后面怎么修改person的name属性的值,name属性的值都不会发生改变
(2)访问器属性
访问器属性不包含数据值,它们包含一对儿getter和setter函数,在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值,在写入访问器属性时,会调用setter函数并传入新值,这个函数负责决定如何处理数据,访问器属性有以下4个特性
a、[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,默认值为true
b、[[Enumerable]]:表示能否通过for-in循环返回属性,默认值为true
c、[[Get]]:在读取属性时调用的函数,默认值为undefined
d、[[Set]]:在写入属性时调用的函数,默认值为undefined
访问器属性不能直接定义,必须调用Object.definedProperty()来定义的,来看下面的例子
function createPerson(name, age) {
var o = new Object();
o.name = name;
o.age = age;
o.sayName = function() {
console.log(this.name);
};
return o;
}
var person1 = createPerson("Nicholas", 29);
var person2 = createPerson("Greg", 27);
优点:能够解决创建多个对象的问题,兼容各个浏览器
缺点:没有解决对象识别的问题,不能知道一个对象的类型
2、构造函数模式
这种模式主要通过创建自定义的构造函数,从而定义自定义对象类型的属性和方法,来看下面例子
console.log(person1 instanceof Person); // true console.log(person2 instanceof Person); // true
使用构造函数模式可以解决对象的识别问题,而这也是工厂模式无法办到的
3、原型模式
我们都知道,每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象就是原型对象,包含了所有实例共享的属性和方法,如果我们要创建的对象需要共享属性和方法,就可以使用这种方法创建
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype = {
constructor: Person,
sayName: function() {
console.log(this.name);
}
}
var person1 = new Person("Nicholas", 29);
var person2 = new Person("Greg", 27);
person1.sayName(); // Nicholas
person2.sayName(); // Greg
person1.sayName === person2.sayName; // true
从上面的例子我们可以看到,使用这种模式创建对象,每个实例都会有自己的一份实例属性的副本,但同时又共享着对方法的引用,最大限度地节省了内存,另外,这种混成模式还支持向构造函数传递参数,可谓是集两种模式之长
5、动态原型模式
这种模式主要是将所有信息都封装在了构造函数里,因为在组合构造函数模式和原型模式中,构造函数和原型模式是独立的,有些开发人员会感到很困惑,因此,这种模式也是为了解决这个问题,通过在构造函数中初始化初始化原型,又保持了同时使用构造函数和原型的优点,换句话说,就是可以通过在构造函数中,检查某个应该存在的方法是否有效,来决定是否需要初始化原型
function Person(name, age) {
var o = new Object();
o.name = name;
o.age = age;
o.sayName = function() {
console.log(this.name);
}
return o;
}
var person1 = new Person("Nicholas", 29);
person1.sayName(); // Nicholas
寄生构造函数模式和工厂模式真的是很像,那么既然有了工厂模式,为什么还要有寄生构造函数模式呢?其实这个模式主要是用来给js原生的构造函数定义一些新的方法,我们可以看下面这个例子
function Person(name, age) {
var o = new Object();
_name = name;
_age = age;
o.sayName = function() {
return _name;
}
return o;
}
var person1 = Person("Nicholas", 29);
person1.sayName(); // Nicholas
在上面这个例子中,我们在构造函数中创建了一个对象后,可以继续添加一些私有的变量和函数,要修改这些私有的变量和函数,只能通过创建的对象的方法进行访问,这里在对象上创建的方法其实可以看作就是公有方法,比如说这里的_name和_age就是私有变量,而对象o的sayName方法就是访问私有变量的公有方法了,这里除了调用sayName()方法外,没有其它方法可以访问其数据成员
8、es6中创建对象的方法
最后要来说下es6中创建对象新增的方法啦,在es6中,引入了 Class(类)这个概念,作为对象的模板,通过class关键字,可以定义类,基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayName() {
console.log(this.name);
}
}
var person1 = new Person("Nicholas", 29);
person1.sayName(); // Nicholas
上面这个例子其实就是组合构造函数模式和原型模式的改写,其中,constructor属性直接指向类本身,该方法会默认返回实例对象,在里面定义的属性和方法都是实例本身具有的方法,不是其它实例共享的,而像sayName方法就是定义在原型上的方法了,是所有实例一起共享的
好啦,今天就介绍到这里了,不知道大家对对象和对象的创建是否有了一个比较详细的了解了呢
__EOF__
- 本文作者: Yellow-ice
- 本文链接:
- 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
- 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角【
Yellow_ice
关注 - 2
粉丝 - 57 我在关注他 上一篇:
下一篇: