一、 target:
- 实现模块化开发
- 避免全局变量污染
二、 实现
1、闭包实现
const Person = (function(){
//共享变量
let share_val = 'i am io';
return function(name,age){
let _name = name, _age = age;
this.setName = function(name){
_name = name;
}
this.setAge = function(age){
_age = age;
}
this.getName = function(){
return _name;
}
this.getAge = function(){
return _age;
}
}
})();
Person.prototype = {
constructor:Person
toString():function(){
return `姓名:${this.getName()}; 年龄:${this.getAge()}`;
}
}
const person_obj = new Person('rkxie',23);
- 描述:用闭包模拟私有方法---模块模式
- 缺点:setter&getter方法同样未定义在原型对象中,增加内存开销
- 优点:共享公共变量&方法
2、对象实现
const Person = function (no,name,age) {
let _no = no, _name = name, _age = age;
return {
setNo: function (no) {
_no = no;
},
setName: function (name) {
_name = name;
},
setAge: function (age) {
_age = age;
},
getAge: function () {
return _age;
},
getName: function () {
return _name;
},
getNo: function () {
return _no;
},
toString: function () {
return `序号: ${this.getNo()};姓名: ${this.getName()}; 年龄: ${this.getAge()}`
}
}
};
const p1 = new Person('abc','def','fgh');
const p2 = Person('abc111','def111','fgh111');
上述new关键字创建的对象和通普通函数返回的对象能达到一致的效果,具体原因见下文相技术点。
3、约定优先原则
function Person(no,name,age) {
this.setNo(no);
this.setName(name);
this.setAge(age);
}
Person.prototype = {
constructor: Person,
setNo:function(no){
this._no = no;
},
getNo:function(){
return this._no;
},
setName:function (name) {
this._name = name;
},
getName:function () {
return this._name;
},
setAge:function (age) {
this._age = age;
},
getAge:function () {
return this._age;
}
};
- 描述:约定所有私有变量以_开头
- 优点:共享setter&getter
- 定义的成员变量可直接访问(变量&方法都定义在原型对象上)
4、严格封装
function Person(no,name,age) {
let _no = no,_name = name,_age = age;
this.setNo = function(no) {
_no = no
};
this.setName = function(name) {
_name = name
};
this.setAge = function(age) {
_age = age
};
this.getNo = function () {
return _no;
};
this.getAge = function () {
return _age;
};
this.getName = function(){
return _name
};
}
Person.prototype = {
constructor:Person,
toString:function () {
return `学号: ${this.getNo()};姓名: ${this.getName()}; 年龄: ${this.getAge()}`;
}
};
- 构造函数中新建成员变量
- 优点:所有成员变量都是能通setter&getter操作
- 缺点:增加内存开销
三、相关技术点
1、this的绑定
基于调用点:谁调用指向谁
- 隐式绑定
- 显式绑定
- apply
- call
- bind
- 关键字new绑定
- 箭头函数绑定
- this的值是函数创建所在的对象 绑定优先级:箭头函数---》new关键字---》显式绑定---》隐式绑定---》默认绑定
2、关键字new
创建一个对象时new关键字所起的作用:
- 创建一个空对象
- var obj = {};
- 将构造函数的作用域赋值给空对象,即:构造函数中的this指向空对象
- obj.__ proto__ = Person.prototype
- Person.call(obj)
- 解释:这句话的意思是给新对象构造原型链,链到构造函数的原型对象,从而新对象就可以访问构造函数中的属性及方法
- 执行构造函数中的代码,为新对象添加属性(call方法)
- 如果构造函数中有返回值则返回,否则返回新对象(return obj)
- 构造函数中有返回:如果返回的是object类型,则返回构造函数中的对象,如果返回除object以外的其他类型(undefined、null、Number、String...)则返回obj
实现一个new:
function Person(name) {
this.name = name;
}
var obj ={};
obj.__proto__ = Person.prototype;
CO.call(obj);
return obj;
或者
function myNew() {
const constr = Array.prototype.shift.call(arguments);
const obj = Object.create(constr.prototype);
const result = constr.apply(obj, arguments);
return result instanceof Object? result : obj;
}
const p = myNew(Person,'xrk');