(学习笔记)javascript创建对象的几种方式,以及es6 class 如何转化成es5代码创建对象
原文地址
1. 最简单的对象字面量和Object构造函数两种方式####
//object构造函数方法
var person = new Object();
person.age = 22;
person.name = 'Dolanf';
person.code = function() {
console.log(‘hello world!’);
};
//字面量方法
var person = {
age: 22,
name: 'Dolanf',
code: function() {
console.log('hello world!');
}
}
但是这两种方法只能创建一个对象,无法进行批量创建,不利于封装。
2. 工厂模式####
function createPerson(age, name) {
var o = new Object();
o.age = age;
o.name = name;
o.code = function() {
console.log('hello world!');
};
return o;
}
var person1 = createPerson(11, '小白');
var person2 = createPerson(12, '小黑');
但是这种方法也有一个问题,那就是我们无法辨别对象。在每一个对象的proto属性中,construction属性都是Object。
3. 构造函数模式和原型模式####
//构造函数模式
function Person(age, name) {
this.age = age;
this.name = name;
this.code = function() {
console.log('hello world!');
};
}
var person1 = new Person(11, '小白');
var person2 = new Person(12, '小黑');
//原型模式
function Person(age, name) {
Person.prototype.age = age;
Person.prototype.name = name;
Person.prototype.code = function() {
console.log('hello world!');
};
}
var person1 = new Person();
var person2 = new Person();
//构造函数+原型组合模式
function Person(age, name) {
this.age = age;
this.name = name;
this.cry = function() {
console.log(name + 'is crying!!! T^T');
}
}
Person.prototype = {
constructor: Person,
sayName: function() {
console.log(this.name);
}
}
var person1 = new Person(11, '小白');
var person2 = new Person(12, '小黑');
这两个模式,分别都走了极端。构造函数模式在创建对象时,每一个属性都会被重新创建。而在原型模式每一个属性只会被创建一次,而且改变其中一个对象的属性,会污染其他对象。而这两者的结合就解决了两方的缺点。
4. es6 class创建对象####
function Person(age, name) {
this.age = age;
this.name = name;
this.cry = function() {
console.log(name + 'is crying!!! T^T');
}
}
Person.prototype = {
constructor: Person,
sayName: function() {
console.log(this.name);
}
}
var person1 = new Person(11, '小白');
var person2 = new Person(12, '小黑');
class Person{
constructor(age, name) {
this.age = age;
this.name = name;
this.cry = function() {
console.log(name + 'is crying!!! T^T');
}
}
sayName() {
console.log(this.name);
}
}
var person1 = new Person(11, '小白');
var person2 = new Person(12, '小黑');
es5和es6 class定义对象的区别
- class的构造函数必须使用new进行调用,普通构造函数不用new也可执行。
- class不存在变量提升,es5中的function存在变量提升。
- class内部定义的方法不可枚举,es5在prototype上定义的方法可以枚举
'use strict'; // es6中class使用的是严格模式
// 处理class中的方法
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
// 默认不可枚举
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
return function (Constructor, protoProps, staticProps) {
if (protoProps) defineProperties(Constructor.prototype, protoProps);
if (staticProps) defineProperties(Constructor, staticProps);
return Constructor;
};
}();
// 对构造函数进行判定
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
// class Person转换为 es5的function
var Person = function () {
function Person(age, name) {
// 调用了_classCallCheck检查Person是否为构造函数
_classCallCheck(this, Person);
this.age = age;
this.name = name;
this.cry = function () {
console.log(name + 'is crying!!! T^T');
};
}
// 调用_createClass处理定义在class中的方法。
_createClass(Person, [{
key: 'sayName',
value: function sayName() {
console.log(this.name);
}
}]);
return Person;
}();
var person1 = new Person(11, '小白');
var person2 = new Person(12, '小黑');