标签:enum 原型 instance create type red 原型式继承 字母 com
面向对象(Object-Oriented,OO)
类
创建Object的实例,然后添加属性和方法
let person = new Object();
person.name = "AAA";
person.sayName = function() {};
对象字面量模式
let person = {
name: "AAA",
sayName: function() {}
};
用特性(attribute)描述属性(property)的各种特征
两种属性:1.数据属性2.访问器属性
1.数据属性
[[configurable]]:能否delete属性后从而重定义属性,能否修改属性的特性,能否把属性修改为访问器属性。默认true。改为false后不可逆。
[[enumerable]]:能否for-in循环返回属性。默认true。
[[writable]]:能否修改属性的值。默认true。
[[value]]:属性的数据值。默认undefined。
let person={name:’AAA’},如此直接定义时特性取默认值和数据值。
1.访问器属性
[[configurable]]:能否delete属性后从而重定义属性,能否修改属性的特性,能否把属性修改为访问器属性。默认true。改为false后不可逆。
[[enumerable]]:能否for-in循环返回属性。默认true。
[[get]]:读取属性时调用的函数。默认undefined。
[[set]]:写入属性时调用的函数。默认undefined。
定义单个
Object.defineProperty(obj, property, descriptor); // descriptor 描述符
descriptor = {
configurable: true,
enumerable: true,
writable: true,
value: "example"
};
定义多个
Object.defineProperties(obj, {
property: {
configurable: true,
enumerable: true,
get: function() {},
set: function() {}
}
});
Object.getOwnPropertyDescriptor(obj,property)
Object.getOwnPropertyDescriptors()
用函数来封装以特定接口创建对象的细节
function createPerson(name) {
let obj = {
name: name,
sayName: function() {
alert(this.name);
}
};
return obj;
}
let person1 = createPerson("lpr");
虽然解决了多个相似对象的问题,但却没有解决对象识别的问题(即怎么知道一个对象的类型)
function Person(name) {
this.name = name;
this.sayName = function() {
alert(this.name);
};
}
let person1 = new Person("lpr");
let person2 = new Person("lpd");
跟工厂模式的不同:
改造函数实际经历4个步骤
这样创建的对象都有一个constructor(构造函数)属性,该属性指向Person
person1.constructor===person2.constructor===Person
person1 instanceof Object // true
person1 instanceof Person // true
意味着可以将它的实例表示为一种特定的类型,但是其中的方法不是同一个Function实例
解决方案:
function Person(name) {
this.name = name;
this.sayName = sayName();
}
function sayName() {
alert(this.name);
}
这样做确实解决了两个函数做同一件事的问题,新问题:1.全局定义的方法直给某一个对象调用,全局作用域名不副实2.多个方法多次在全局定义函数,没有封装性
function Person() {}
Person.prototype.name = "AAA";
Person.prototype.sayName = function() {};
let person1 = new Person();
let person2 = new Person();
person1.sayName===person2.sayName
Person.prototype.isPrototypeOf(person1); // true
Object.getPrototypeOf(person1) === Person.prototype; // true
person1.hasOwnProperty("name"); // 是否自身存在属性
alert("name" in person1); // 属性是否存在于自身或原型中
可组合判断属性存在实例还是原型中
Object.keys(obj); // 获取对象上所有可枚举的实例属性,返回结果是key的数组
Object.getOwnPropertyNames(); // 获取对象上所有的实例属性,无论是否可枚举,如‘constructor‘
function Person() {}
Person.prototype = {
constructor: Person,
// 每创建一个函数会同时创建它的prototype对象,这个对象也会自动获取constructor属性。
// 如果不重新指定,即实例的constructor不指向Person
// 即person1.constructor !== Person,因此要重新指定建立联系
// 不过这种方式会使constructor属性的特性[[Enumerable]]为true,变为可枚举
name: "AAA",
sayName: function() {
console.log(this.name);
}
};
Object.defineProperty(Person.prototype, "constructor", {
enumerable: false,
value: Person
});
重写原型对象切断了现有原型与任何之前已经存在的对象实例之间的联系
不推荐修改原生对象的原型
例如原型中有个属性时数组,在实例中push,则添加到了原型中的数组里。即变成共享。
构造函数定于实例属性,原型模式定于方法和共享方法。
每个实例都有自己的一份实例属性,又同时共享对方法的应用。是使用最广泛、认同度最高的创建自定义类型的方法。
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
};
function SubType() {
this.subproperty = false;
}
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function() {
return this.subproperty;
};
let instance = new SubType();
alert(instance.getSuperValue()); // true
最顶层的原型为Object.prototype
instance instanceof Object
instance instanceof SuperType
instance instanceof SubType
都为true
Object.prototype.isPrototypeOf(instance)
SuperType.prototype.isPrototypeOf(instance)
SubType.prototype.isPrototypeOf(instance)
都为true
给原型添加方法的代码一定要放在替换原型的语句之后
通过原型链实现继承时,不能使用对象字面量创建原型方法。因为这样做会重写原型链
function SuperType() {
this.color = ["red", "green", "blue"];
}
function SubType() {
SuperType.call(this); //借调了超类型的构造函数
}
function SuperType(name) {
this.name = name;
}
function SubType() {
SuperType.call(this, "lpr");
}
function SuperType(name) {
this.name = name;
this.color = ["red", "green", "blue"];
}
SuperType.prototype.sayName = function() {
alert(this.name);
};
function SubType(name, age) {
SuperType.call(this, name);
this.age = age;
}
SubType.prototype = new SuperType();
SubType.constructor = SubType;
SubType.prototype.sayAge = function() {
alert(this.age);
};
let instance1 = new SubType("lpr", 17);
instance1.color.push("black"); // ["red", "green", "blue","black"]
instance1.sayName(); // ‘lpr‘
instance1.sayAge(); // 17
let instance2 = new SubType("lpd", 16);
instance2.color; // ["red", "green", "blue"]
instance1.sayName(); // ‘lpd‘
instance1.sayAge(); // 16
标签:enum 原型 instance create type red 原型式继承 字母 com
原文地址:https://www.cnblogs.com/Mijiujs/p/12080348.html