您的位置:首页 > Web前端 > JavaScript

js oop之原型与原型链

2017-03-09 09:48 106 查看
对象
在大多数语言中都是以面向对象(OOP)进行编程,在JavaScript语言中也不例外。那么今天就来探讨一下JavaScript的面向对象。

面向对象的三大特性:

1. 封装:在面向对象语言中,封装特性是由类来体现的,我们将现实生活中的一类实体定义成类,其中包括属性和行为。例如动物这一类,有name,sex,age等属性,拥有eat()、sleep()、listen()等方法。

2. 继承:继承就像是我们现实生活中的父子关系,儿子可以遗传父亲的一些特性,在面向对象语言中,就是一个类可以继承另一个类的一些特性,从而可以代码重用,其实继承体现的是is-a关系,父类同子类在本质上还是一类实体;

3. 多态:多态就是通过传递给父类对象引用不同的子类对象从而表现出不同的行为,多态可为程序提供更好的可扩展性,同样也可以代码重用。因为js是弱类型语言,所以不能实现多态。

继承、封装我会在js高阶(二)详细讲解。

JavaScript如何体现OOP:

1.基于原型的面向对象的思维。

2.没有对象,没有类,对象继承对象,而不是类继承类

3.原型对象是基于语言的核心概念,原型对象是新的对象模板。

对象的构成:属性(对象的状态)和方法(可实施的动作)。

要想了解原型和原型链还要知道作用域

作用域:作用域是JavaScript最重要的概念之一,任何程序设计语言都有作用域的概念,简单的说,作用域就是变量与函数的可访问范围,即作用域控制着变量与函数的可见性和生命周期。在JavaScript中,变量的作用域有全局作用域和局部作用域两种。


1.  全局作用域(Global Scope)

在代码中任何地方都能访问到的对象拥有全局作用域:      

var a=100;
 //全局变量

function test(){
 

    console.log(a);  //100

}  

test();


2. 局部作用域(Global Scope)

var a=100;
 //全局变量

function test(){
 

    console.log(a);  //undefined

    var a=10; //局部变量

    console.log(a); //10

}  

test();

为什么第一个 console.log(a);  结果为undefined;而不是100?;这个就要结合原型链来解释。首先这个a要去找函数里面的a,函数里面已经定义了a,但是在a没有执行,所以为undefined,如果函数里面没有a变量,那么会根据原型链去找上一级和原型上的变量。

原型

在JavaScript 中,每当定义一个对象(函数)时候,对象中都会包含一些预定义的属性。其中函数对象的一个属性就是原型对象
prototype。注:普通对象没有prototype,但有__proto__属性。原型对象其实就是普通对象(Function.prototype除外,它是函数对象,但它很特殊,他没有prototype属性(前面说道函数对象都有prototype属性))。

function
fn(){};

 console.log(fn.prototype)
//fn{}
 console.log(typeof fn. prototype) //Object
 console.log(typeof Function.prototype) // Function,这个特殊
 console.log(typeof Object.prototype) // Object
 console.log(typeof Function.prototype.prototype) //undefined

从这句console.log(fn.prototype)
//fn {} 的输出就结果可以看出,fn.prototype就是fn的一个实例对象。就是在f1创建的时候,创建了一个它的实例对象并赋值给它的prototype,基本过程如下:
 var temp = new fn();
 fn. prototype = temp;
 所以,Function.prototype为什么是函数对象就迎刃而解了,上文提到凡是new Function ()产生的对象都是函数对象,所以temp是函数对象。
 var temp= new Function ();
 Function.prototype = temp;

原型链

JS在创建对象(不论是普通对象还是函数对象)的时候,都有一个叫做__proto__的内置属性,用于指向创建它的函数对象的原型对象prototype。

var person = function(name){
   this.name = name
  };
  person.prototype.getName = function(){
     return this.name; 
  }
  var p1 = new person(‘zhou’);
  p1.getName(); //zhou

console.log(p1.__proto__ === person.prototype)
//true

同样,person.prototype对象也有__proto__属性,它指向创建它的函数对象(Object)的prototype

  console.log(person.prototype.__proto__ === Object.prototype) //true

继续,Object.prototype对象也有__proto__属性,但它比较特殊,为null

  console.log(Object.prototype.__proto__) //null
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: