深入解读JavaScript面向对象编程实践

   Javascript是一门解释性脚本语言,同时它也是一门面向对象编程语言,但是它跟Java,c++等又不一样,因为它没有类(class),那么我们要如何把属性(

property)和方法(method)封装成一个对象,从原型对象实例化出来一对象呢?

一、对象类的创建

在JavaScript中,我们通常可以使用构造函数来创建特定类型的对象。诸如Object和Array这样的原生构造函数,在运行时会自动出现在执行环境中。 此外,我们也可以创建自定义的构造函数。

1 function  Man(name, age, job) {
2   this.name = name;
3   this.age = age;
4   this.job = job;
5 }
6 var man1 = new Person('Weiwei', 27, 'Student');
7 var man2 = new Person('Lily', 25, 'Doctor');

   

 按照惯例,构造函数始终都应该以一个大写字母开头(和Java中定义的类一样),普通函数则小写字母开头。 要创建Person的新实例,必须使用new操作符。

这样调用构造函数一般经过一下四个步骤:

  1. 创建一个新对象(实例)
  2. 将构造函数的作用域赋给新对象(也就是重设了this的指向,this就指向了这个新对象)
  3. 执行构造函数中的代码(为这个新对象添加属性)
  4. 返回新对象

  在上面的例子中,person1,person2 会默认都有一个constructor 属性,该属性指向它们的构造函数Man,即为

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

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

二、prototype 原型问题

来看这段代码:

 1 function Man(name,age,job) {
 2 this.name = name ;
 3 this.age  = age;
 4 this.job = job;
 5 this.type = "person" ;
 6 this.action =function(){
 7 alert('walk');
 8 }
 9 }
10 
11 man1 = new Man("wei","20","student"); 12 console.log(man1.type); 13 //person

  这样子看起来好像没什么问题,但其实每次实例化,实例的 type 和 action 都是一样的, 这样就造成多次重复,占用了内存,实际上javascript规定,每个构造函数都有一个 prototype 属性,指向另一个对象,这个对象所有属性和方法,都会被实例化继承。

  也就是说,我们可以把那些不会变得属性和方法全部定义在 prototype 对象上。

1 function Man(name,age,job){
2     this.name = name;
3     this.age = age;
4        this.job = job;
5   }
6   Man.prototype.type = "person";
7   Cat.prototype.action = function(){alert("walk")};

然后生成实例;

1  man1 =new Man("wei","20","student"); 

2 alert(man1.type); //person

 

上图展示了Man构造函数、Man的原型对象以及Man现有的实例之间的关系。

  • Person.prototype指向了原型对象
  • Person.prototype.constructor又指回了Person构造函数
  • Person的实例man1一个内部属性(通常为__proto__),man1.__proto__指向了原型对象

 三、 Prototype模式的验证方法

  为了配合 prototype 属性,javascript 定义了一些方法,帮助我们使用它。

 3.1   isPrototypeOf()

   这个方法用来判断,某个proptotype对象和某个实例之间的关系。

1 alert(Man.prototype.isPrototypeOf(man1));
2 // true;

3.2  hasOwnProperty()

每个实例对象都有一个 hasOwnProperty ()方法用于判断某一属性是来自本地属性,还是继承自prototype对象,若来自本地返回 true,否则返回 false;

1 man1.hasOwnProperty("name");
2 man1.hasOwnProperty("type");
3 //true
4 //false

3.3 in 运算符

同样 可以用 for in 来遍历对象

1 for(var prop in man1){
2 console.log("man1["+prop+"] = "+man1[prop]);
3 }
4 //man1[name] = ben
5 // man1[age] = 20
6 // man1[job] = student
7 //man1[type] = person
8 // man1[action] = function (){alert("walk")}

同时 in 也可以用来检测属性是否在对象内,不管是本地对象,还是prototype 的属性

 1 console.log("eat" in man1);
 2 //false
 3 undefined
 4 console.log("type" in man1);
 5 
 6 //  true
 7 
 8 console.log("name" in man1);
 9 
10 //true
原文地址:https://www.cnblogs.com/benstos/p/5726982.html