[关闭]
@Dreamingboy 2017-03-19T14:47:23.000000Z 字数 3302 阅读 864

第三周学习笔记

学习笔记

6.2 创建对象

6.2.1 工厂模式

使用一个函数来将属性和方法封装起来,然后其他对象直接调用这个函数就可以自动创建函数里面的属相和方法,这样可以极大减少代码量。

function a(name,age,job) {
var b = new Object();
b.name=name;
b.age=age;
b.job=job;
return b;}
var c = a("mike", 12, "teacher");
c;//Object {name: "mike", age: 12, job: "teacher"}

上面的return语句是关键

6.2.2 构造函数模式

function A(name,age,job) {
this.name=name;
this.age=age;
this.job=job;
}
var c = new A("mike", 12, "teacher");
c;//A {name: "mike", age: 12, job: "teacher"}

使用构造函数模式与工厂模式的区别

上面使用new创建一个构造函数后经历下面的过程
- 创建新对象
- 将构造函数的作用域赋给新对象
- 执行构造函数的代码
- 返回新对象
任何函数通过new操作符调用,那它就是构造函数,如果不通过new操作符则是普通的函数

1、构造函数的问题
构造函数的最大问题是每个方法都要在实例上面创建一遍

6.2.3 原型模式

每个函数都有一个prototype(原型)属性,这是一个指针,指向一个对象,这个对象包含可以由特定类型的所有实例共享的属性和方法,也就是说所有的对象实例都可以共享这个对象的属性和方法。

function person(){
person.prototype.name="bob",
person.prototype.work="teacher",
person.prototype.age=24
person.prototype.sayname = function(){
alert(this.name);
 }
}
var person1=new person();
person1.sayname();//"bob"
var person2=new person();
person2.sayname();//"bob"

1、理解原型对象
当我们创建一个构造函数时会自动创建一个prototype的属性,这个属性指向构造函数的原型对象,原型对象本身自带的一个属性是constructor,这是一个指向原构造函数的指针,原型对象中的其他属性都是从构造函数那边继承过来的。当创建构造函数的一个实例时,这个实例就会自带一个[[Prototype]]属性,这个属性是一个指向原型对象的指针。需要明确的是实例和构造函数之间并没有直接的联系,即实例没有直接指向构造函数

使用Object.getPropertyOf()通过实例取得原型对象(以上面的person为例)

var b = Object.getPropertyOf(person1).name;
b;//"bob"

读取对象的某个属性时,首先搜索实例,如果实例里面有这个属性的值,就停止搜索,如果没有,就会继续想原型对象搜索,直到找到,否则则返回没有

不可以通过实例重写原型中的值

function person(){
person.prototype.name="bob",
person.prototype.work="teacher",
person.prototype.age=24
person.prototype.sayname = function(){
alert(this.name);
 }
}
var person1=new person();
person1.sayname();//"bob"
var person2=new person();
person2.sayname();//"bob"
var person1.name="mike";
person1.name;//"mike"
person2.name;//"bob"

hasOwnProperty()检测一个属性是存在于实例还是原型,在给定属性存在于对象实例中时返回true
以上面的代码为例:

alert(person1.hasOwnProperty("name"))//true
alert(person2.hasOwnProperty("name"))//flase

2、原型与in操作符
in操纵符的两中使用情况:单独使用、for-in语句
单独使用时,in会在通过对象可以访问到属性时返回true,无论该属性时再实例中还是在原型中。
根据之前的person实例,看下面的例子

alert("name" in person1)//true

for-in:返回所有能够通过对象访问的、课枚举的属性,包括实例和原型中的。屏蔽了原型中不可枚举的实例属性([[Enumerable]]标记为false)也会返回。

3、更简单的原型语法
用一个包含所有属性和方法的对象来写原型对象

function Person(){
Person.prototype={
constructor: Person,//如果省略这句,那么constructor不再指向Person
name:"bob",
age:12,
job:"teacher",
Sayname: function(){
alert(this.name)
  }
 }
}

上面的写法实质上是重写了原型对象,在这种情况下,constructor不会指向原来的构造函数,而上面的代码将constructor的值设置成Person后会导致constructor的[[Enumerable]]特性被设置成true,但是默认情况下是false,此时对于兼容ECMAScript5的Object.defineProperty()

 function Person(){
Person.prototype={
name:"bob",
age:12,
job:"teacher",
Sayname: function(){
alert(this.name)
  }
 }
}
Object,defineProperty(Person.prototype,"constructor",{
    enumerable:false,
    value:Person
    });

4、原型的动态性
原型的动态性是因为实例与原型的之间连接是松散性的,原型所做的任何修改都可以再实例上面体现出来。

5、原生对象的原型

6、原型对象的问题

6.2.4 组合使用构造函数模式和原型模式

用构造函数定义实例属性,原型模式定义共同的属性和方法。

function Person(name,age,job){
     this.name = name;
     this.age = age;
     this.job = job;
     this.friend = ["tom","bob"];
     }
var Person.prototype={
   constructor:Person,
   sayname: fuction{
               alert(this.name);
 }
}

  var person1 = new Person();
   person1.friend.push("jim");
   var person1.friend;//["tom","bob""jim"]
   var person2 = new Person();
   person2.friend;//["tom","bob"]
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注