每个对象都是基于引用类型建立的, 也能够是开发人员本身建立的数组
工厂模式
let Person = {
name: 'agan',
age: 30,
job: 'it',
sayName: function() {
console.log(this.name)
}
}
复制代码
这种模式抽象了建立具体函数的过程, 用函数来封装以特定接口建立对象的细节函数
function createPerson(name, age, job) {
let o = new Object()
o.name = name
o.age = age
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
let p1 = createPerson('agan1', 30, 'it')
let p2 = createPerson('agan2', 40, 'cs')
复制代码
函数 createPerson
接受三个参数来构建一个对象, 该函数能够屡次调用. 工厂模式虽然解决了建立多个类似对象的问题, 却没有解决对象识别的问题(即怎样知道一个对象的类型)ui
构造函数能够用来建立特定类型的对象, 咱们能够建立自定义的构造函数, 从而能够定义自定义对象类型的属性和方法this
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
this.sayName = function() {
console.log(this.name)
}
}
let p1 = new Person('agan1', 30, 'it')
let p2 = new Person('agan2', 40, 'cs')
复制代码
Person
与 createPerson
不一样:spa
this
return
语句p1
和 p2
保存着 Person
的两个不一样实例, 但都有一个 constructor
(构造函数) 属性, 指向 Person
prototype
console(p1.constructor == Person); //true
console(p2.constructor == Person); //true
复制代码
constructor
是用来表示对象类型的, instanceof
检测对象类型更靠谱指针
alert(person1 instanceof Object); //true
alert(person1 instanceof Person); //true
alert(person2 instanceof Object); //true
alert(person2 instanceof Person); //true
复制代码
var p1=new Person();
code
_p1
this
,将this指向该实例(_p1)a、若是函数没有返回值(没有return语句),那么就会返回构造函数的实例(p1)对象
b、若是函数返回了一个基本数据类型的值,那么本次构造函数的返回值是该实例(_p1)接口
function fn(){}
var f1 = new fn(); //f1就是fn的实例
function fn2(){
return "abc";
}
var f2 = new fn2(); //f2是fn2构造函数的实例
复制代码
c、若是函数返回了一个复杂数据类型的值, 那么本次函数的返回值就是该值
function fn3(){
return [1,3,5];
//数组是一个对象类型的值,
//因此数组是一个复杂数据类型的值
//-->本次构造函数的真正返回值就是该数组
//-->再也不是fn3构造函数的实例
}
var f3 = new fn3(); //f3仍是fn3的实例吗?错
//f3值为[1,3,5]
复制代码
new
调用new
调用就是普通函数// 看成构造函数
let person = new Person("agan", 29, "se");
person.sayName() // 'agan'
// 做为普通函数调用
Person("agan1", 27, "IT"); // 添加到 window
window.sayName(); // "agan1"
// 在另外一个对象的做用域中调用
var o = new Object();
Person.call(o, "agan3", 25, "Nurse")
o.sayName(); // "agan3"
复制代码
就是每一个方法都要在每一个实例上从新建立一遍,
sayName
指向不一样的地址
person1.sayName === person2.sayName // true
复制代码
能够将 sayName 方法转移到构造函数外部解决这个问题
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
this.sayName = sayName
}
function sayName() {
console.log(this.name)
}
let person1 = new Person("agan1", 29, "se");
let person2 = new Person("agan2", 27, "it");
person1.sayName === person2.sayName // true
复制代码
上面代码中将 sayName
函数转移到了构造函数的外部, 在函数内部咱们将 sayName
指向这个全局函数, 这样就解决了多个函数作一件事情的问题, 但又带来了两个新的问题:
咱们建立的每个函数都有一个
prototype
属性, 这是一个指针, 指向了一个对象, 这个对象包含了特定类型对象的全部公共属性和方法, 至关于一个父类
function Person() {
}
Person.prototype.name = 'agan'
Person.prototype.age = '30'
Person.prototype.job = 'it'
Person.prototype.sayName = function() {
console.log(this.name)
}
let p1 = new Person()
let p2 = new Person()
p1.sayName() // 'agan'
p2.sayName() // 'agan'
console.log(p1.sayName === p2.sayName) // true
复制代码
上述代码中 person1
和 person2
访问的是同一组对象和方法 假如咱们想在全部的实例中共享一个数据, 那么咱们可使用原型模式, 但是通常实例都有本身的属性
构造函数用于建立实例属性, 原型模式用于定义方法和共享的属性
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
this.friends = ['a', 'b']
}
Person.prototype = {
constructor: Person,
sayName: function() {
console.log(this.name)
}
}
var p1 = new Person('agan', 29, 'it')
var p2 = new Person('agan2', 30, 'cs')
p1.friends.push('c')
console.log(p1.friends) // 'a' 'b' 'c'
console.log(p2.friends) // 'a' 'b'
console.log(p1.friends === p2.friends) // false
console.log(p1.sayName === p2.sayName) // true
复制代码
在上面的代码中, 实例属性是定义在构造函数中的, 实例共享的属性和方法是在原型中定义的
动态原型模式将全部信息都封装在了构造函数中, 在构造函数中初始化原型
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
// 方法
if (typeof this.sayName !== 'function') {
Person.prototype.sayName = function() {
console.log(this.name)
}
}
}
let f = new Person('agan', 30, 'it')
f.sayName()
复制代码
上述代码中, sayName方法只有在不存在的状况下, 才会添加到原型中, 这段代码只会在初次调用构造函数时才会执行
基本思想: 建立一个函数, 该函数用来封装建立对象的代码, 而后再返回建立的对象 跟工厂模式相似
function Person(name, age, job) {
let o = new Object()
o.name = name
o.age = age
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
let f = new Person('agan', 20, 'it')
f.sayName() // 'agan'
复制代码
稳妥对象: 指的是没有公共属性, 其方法也不引用
this
对象
this
new
操做符调用构造函数function Person(name, age, job) {
let o = new Object()
// 定义私有变量和函数
let name = name
let age = age
let job = job
// 添加方法
o.sayName = function() {
console.log(name)
}
return o
}
复制代码
这种模式中建立的对象, 除了使用 sayName
方法外没有其余方法访问name的值
let f = Person('agan', 30, 'it')
f.sayName() // agan
复制代码