最近看NCZ的JS高级程序设计整理的一些代码
// 6.2.4 组合使用构造函数和原型模式————创建自定义对象的方法:
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.friends = ["Shelby", "Court"];
}
Object.defineProperties(Person.prototype, {
"constructor": {
enumerable: false,
value: Person,
},
"sayName": {
enumerable: true,
value: function() {
console.log(this.name)
}
}
})
var person1 = new Person("Nicholas", 29, "Software Engineer");
// 6.2.5动态原型模式————将原型封装到构造函数中:
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
// 只在第一次使用构造函数时if块内的语句才会执行
if (typeof this.sayName.toLowerCase() != "function") {
Person.prototype.sayName = function() {
console.log(this.name);
}
}
}
var person1 = new Person("Nicholas", 29, "Software Engineer");
// 6.2.6 寄生构造函数模式————用于为原生构造函数定义新的方法,避免污染原生构造函数
function Person(name, age, job) {
var obj = new Object();
obj.name = name;
obj.age = age;
obj.job = job;
obj.sayName = function() {
console.log(this.name);
}
return obj;
}
// 与工厂模式的区别是多了一个new操作符
var person1 = new Person("Nicholas", 29, "Software Engineer");
// ________________________________________________________________________
//寄生构造函数模式可以构造基于特殊对象(如数组)创建的具有指定方法的特殊对象
function SpecialArray() {
var values = new Array();
values.push.apply(values, arguments);
values.toPipedString = function() {
return values.join("|");
}
return values;
}
// 6.2.7 稳妥构造函数模式————将变量封装到构造函数内部,不能通过对象属性访问,只能通过对象方法访问
function Person(name, age, job) {
var obj = new Object();
obj.sayName = function() {
console.log(name);
}
return obj
}
var person1 = Person("jusing");
// 只能通过person1.sayName()方法访问"jusing";person1对象实例中没有name属性
// 6.3.3 组合继承模式(原型链+构造函数)
// !!!!!!!最常用的继承方法!!!!!!!
//先定义超类型构造函数,绑定属性
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
// 再定义超类型构造函数的原型,绑定方法;
SuperType.prototype.sayName = function() {
console.log(this.name);
}
// 定义子类型构造函数
function SubType(name, age) {
// 通过向子类型传参,设置子类型实例的属性值;
SuperType.call(this, name);
this.age = age;
}
// 将子类型的原型设置为超类型的对象实例
SubType.prototype = new SuperType();
Subtype.sayAge = function() {
console.log(this.age);
}
// 6.3.4 原型式继承————直接以对象实例为原型创建构造函数并返回子类型对象实例
// ECMAScript为原型式继承提供了原生方法: Object.create(obj, [A-V Object]),这个方法接受两个参数,第一个是原型对象,第二个为键值对象(可选)
function object(obj) {
function F() {};
F.prototype = obj;
return new F();
}
var person = {
name: "jusing",
friends: ["Shelby", "Court", "Van"]
}
person1 = object(person);
// 6.3.5 寄生式继承————在主要考虑对对象实例的继承而不是自定义子类型对象的属性时,简单易用
function createAnother(obj) {
var clone = Object.create(obj);
// 增强对象的方法
clone.sayHi = function() {
console.log("Hi!");
}
return clone;
}
// 注意在使用寄生式继承方法为对象添加方法时不能做到方法的复用,会浪费大量的资源
// 6.3.6 寄生组合式继承————避免在超类型.prototype上创建多余的属性,还能保证原型链的不变。
// 这是开发人员普遍认为最完美的继承方法
function inheritPrototype(subtype, supertype) {
// 创建超类型的原型对象作为子类型的原型
var prototype = Object.create(supertype.prototype);
// 将超类型的原型.constructor指向子类型构造函数
prototype.constructor = subType;
// 将子类型构造函数的原型指向超类型的原型
subType.prototype = prototype;
}
//先定义超类型构造函数,绑定属性
function SuperType(name) {
this.name = name;
this.colors = ["red", "blue", "green"];
}
// 再定义超类型构造函数的原型,绑定方法;
SuperType.prototype.sayName = function() {
console.log(this.name);
}
// 定义子类型构造函数
function SubType(name, age) {
// 通过向子类型传参,设置子类型实例的属性值;
SuperType.call(this, name);
this.age = age;
}
// 实现寄生组合继承方法
inheritPrototype(SubType, SuperType);
// 为超类型的原型(此时已成为子类型构造函数的原型)添加方法
SubType.prototype.sayAge = function() {
console.log(this.age);
}
// 6.3.7 深度克隆————完全克隆一个引用值,但是不包括其原型链
function deepClone(origin, target) {
var target = target || {},
toStr = Object.prototype.toString,
arrStr = "[object Array]";
for(var prop in origin) {
// 过滤掉origin.prototype原型链上的属性
if (origin.hasOwnProperty(prop)) {
// 针对origin上非null的对象属性
if(origin[prop] !== "null" && typeof(origin[prop]) == "object") {
// 判断是否为origin[prop]是否为数组对象
if(toStr.call(origin[prop]) == arrStr) {
target[prop] = [];
}
// 否则为对象
else {
target[prop] = {};
}
// 对数组与对象属性进行递归方法
deepClone(origin[prop], target[prop]);
}
// 字符串等基本类型直接copy
else {
target[prop] = origin[prop];
}
}
}
return target;
}
// 7.4 私有变量————只能通过特权方法访问函数内部变量
function MyObject() {
// 创建私有变量和私有函数
var privateVriable = 10;
function privateFunction() {
return false;
}
// 特权方法
this.publicMethod = function() {
console.log(privateVriable ++, privateFunction());
}
}
// 这种方法会导致特权方法重复绑定,复用性不好
7.4.1 静态私有变量————解决私有方法的复用性问题
(function() {
// 创建私有变量和私有函数
var privateVriable = 10;
function privateFunction() {
return false;
}
// 使用构造函数及原型绑定私有变量与函数
MyObject = function() {}; //这里没有用new操作符,将MyObject定义为全局变量,函数执行后可访问
//原型
MyObject.prototype.publicMethod = function() {
console.log(privateVriable ++, privateFunction());
}
})
7.4.3 增强的模块模式————私有变量、方法复用、对象增强
var singleton = function() {
var privateVriable = 10;
function privateFunction() {
return false;
}
var object = new CustomType();
object.publicProperty = true;
object.publicMethod = function() {
console.log(privateVriable ++, privateFunction());
}
return object;
}();
上一篇: 在清朝时期,后宫的嫔妃是如何打发时间的?
下一篇: 为什么韩信北伐一次就成功了?