js-原生对象

工厂模式:
多个类似对象的创建,可以使用工厂模式,但工程模式不知道新创建的对象是什么类型。

构造函数模式:
使用构造函数创建对象:

function Person(name, age, job){ 
 this.name = name; 
 this.age = age; 
 this.job = job; 
 this.sayName = function() { 
 console.log(this.name); 
 }; 
} 
let person1 = new Person("Nicholas", 29, "Software Engineer"); 
let person2 = new Person("Greg", 27, "Doctor");

person1和person2实例对象的constructor都指向Person,因此构造函数可以区分实例为哪种类型。
这是相比工厂模式/构造函数模式所具有的优点

console.log(person1.constructor == Person); // true 
console.log(person2.constructor == Person); // true

只要使用new操作符,调用的就是构造函数。不使用new操作符的就是普通函数。

构造函数的缺点:在构造函数中定义的方法,在每个实例上都不同,并不是共享一个操作方法。

解决方案是,将方法单独定义在构造函数的外部,但是形成的问题是为实例赋予方法的引用的时候,会使用全局的方法的应用,这样会导致全局变量的混乱。
因此可使用原型模式来解决这些问题。

原型模式:
在原型对象上创建属性和方法。

function Person() {} 
Person.prototype.name = "Nicholas"; 
Person.prototype.age = 29; 
Person.prototype.job = "Software Engineer"; 
Person.prototype.sayName = function() { 
 console.log(this.name); 
}; 
let person1 = new Person(); 
person1.sayName(); // "Nicholas"

原型上的属性和方法,都被所有的属性和方法共享。

理解原型:
定义构造方法时,原型对象上就有了constructor属性。指向与之关联构造函数。

注意:构造函数。实例。原型对象,都是不同的对象。

原型层级覆盖:如果在对象的属性找没有找到对应的方法或属性,那么就会去它的原型对象上去找对应的方法或属性。
如果存在同名的属性,那么会覆盖到原型对象上的属性。

原型和in操作符
in操作符:可以通过对象属性名,判断该属性名是否在于对象或者对象的原型上

定义原型的语法:

function Person() {} 
Person.prototype = {
 name: "Nicholas", 
 age: 29, 
 job: "Software Engineer", 
 sayName() { 
 console.log(this.name); 
 } 
};

上述方法,会将constructor指向object对象,而它应该指向的是相关的构造函数,因此可以单独设置constructor

} 
Person.prototype = { 
 constructor: Person, 
 name: "Nicholas", 
 age: 29, 
 job: "Software Engineer", 
 sayName() { 
 console.log(this.name); 
 } 
};

但上述方法又存在了新的问题。这样会创建的一个Enumerable为true的属性。而原生的constructor是不可枚举的。
因此添加以下方式来进行给更改:

function Person() {} 
Person.prototype = { 
 name: "Nicholas", 
 age: 29, 
 job: "Software Engineer", 
 sayName() { 
 console.log(this.name); 
 } 
}; 
// 恢复 constructor 属性
Object.defineProperty(Person.prototype, "constructor", { 
 enumerable: false, 
 value: Person 
});

原型的动态性:
如果先创建了对象,然后再在对象的原型上进行了修改,那么仍然会改变之前已经创建好的对象。
这是因为实例与原型之间就是简简单单的指针。会在原型上找到对应修改的属性。

原生对象原型:
修改原生的String对象

String.prototype.startsWith = function (text) { 
 return this.indexOf(text) === 0; 
}; 
let msg = "Hello world!"; 
console.log(msg.startsWith("Hello")); // true

但并不建议这么做。推荐的做法是使用继承。

原型的问题:
原型上包含引用属性值,会存在问题。

继承:
原型链:
将对象原型指针,更改为指向另外一个对象。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值