(學(xué)習(xí)筆記)javascript創(chuàng)建對象的幾種方式,以及es6 class 如何轉(zhuǎn)化成es5代碼創(chuàng)建對象
1. 最簡單的對象字面量和Object構(gòu)造函數(shù)兩種方式####
//object構(gòu)造函數(shù)方法
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!');
}
}
但是這兩種方法只能創(chuàng)建一個對象,無法進(jìn)行批量創(chuàng)建,不利于封裝。
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. 構(gòu)造函數(shù)模式和原型模式####
//構(gòu)造函數(shù)模式
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();
//構(gòu)造函數(shù)+原型組合模式
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, '小黑');
這兩個模式,分別都走了極端。構(gòu)造函數(shù)模式在創(chuàng)建對象時,每一個屬性都會被重新創(chuàng)建。而在原型模式每一個屬性只會被創(chuàng)建一次,而且改變其中一個對象的屬性,會污染其他對象。而這兩者的結(jié)合就解決了兩方的缺點(diǎn)。
4. es6 class創(chuàng)建對象####
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定義對象的區(qū)別
- class的構(gòu)造函數(shù)必須使用new進(jìn)行調(diào)用,普通構(gòu)造函數(shù)不用new也可執(zhí)行。
- class不存在變量提升,es5中的function存在變量提升。
- class內(nèi)部定義的方法不可枚舉,es5在prototype上定義的方法可以枚舉
'use strict'; // es6中class使用的是嚴(yán)格模式
// 處理class中的方法
var _createClass = function () {
function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
// 默認(rèn)不可枚舉
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;
};
}();
// 對構(gòu)造函數(shù)進(jìn)行判定
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
// class Person轉(zhuǎn)換為 es5的function
var Person = function () {
function Person(age, name) {
// 調(diào)用了_classCallCheck檢查Person是否為構(gòu)造函數(shù)
_classCallCheck(this, Person);
this.age = age;
this.name = name;
this.cry = function () {
console.log(name + 'is crying!!! T^T');
};
}
// 調(diào)用_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, '小黑');