Javascript是一种基于原型的语言,和咱们一般的Class based programming有很大的区别:编程
1. 函数式first class object,也就是说函数与对象具备相同的语言地位
数组
2. 没有类,一切基于对象函数
3. 函数也是一种对象,所谓的函数对象
this
4. 对象是按引用来传递的
spa
每一个韩式都有一个prototype属性,这个属性指向一个对象的引用,这个对象成为原型对象,源性对象包含函数实例共享的方法和属性,也就是说讲函数用做构造函数调用(使用new操做符调用)的时候,新建立的对象会从原型对象上继承属性和方法。prototype
先来弄清一个概念:
orm
私有变量,函数对象
JavaScript的做用域链,通俗讲就是函数内定义的变量和函数若是不对外提供接口,那么外部将没法访问到,就成为了私有变量和私有函数。继承
代码以下: |
function Obj(){接口 var a = 0; //私有变量 var fn = function(){ } //私有函数 } |
这样的函数对象Obj外部没法访问变量a和函数fn,他们变成私有的,只能在Obj内部使用,即便是函数Obj的实例仍然没法访问这些变量和函数。 |
静态变量、函数
当定义一个函数后经过 “.”为其添加的属性和函数,经过对象自己仍然能够访问获得,可是其实例却访问不到,这样的变量和函数分别被称为静态变量和静态函数,用过Java、C#的同窗很好理解静态的含义。
复制代码代码以下:
function Obj(){ |
实例变量、函数
在面向对象编程中除了一些库函数咱们仍是但愿在对象定义的时候同时定义一些属性和方法,实例化后能够访问,JavaScript也能作到这样
function Obj(){ this.a=[]; //实例变量 this.fn=function(){ //实例方法 } } console.log(typeof Obj.a); //undefined console.log(typeof Obj.fn); //undefined var o=new Obj(); console.log(typeof o.a); //object console.log(typeof o.fn); //function |
新的实例会有新的引用
function Obj(){ this.a=[]; //实例变量 this.fn=function(){ //实例方法 } } var o1=new Obj(); o1.a.push(1); o1.fn={}; console.log(o1.a); //[1] console.log(typeof o1.fn); //object var o2=new Obj(); console.log(o2.a); //[] console.log(typeof o2.fn); //function |
上面的代码运行结果彻底符合预期,但同时也说明一个问题,在o1中修改了a和fn,而在o2中没有改变,因为数组和函数都是对象,是引用类型,这就说明o1中的属性和方法与o2中的属性与方法虽然同名但却不是一个引用,而是对Obj对象定义的属性和方法的一个复制。
这个对属性来讲没有什么问题,可是对于方法来讲问题就很大了,由于方法都是在作彻底同样的功能,可是却又两份复制,若是一个函数对象有上千和实例方法,那么它的每一个实例都要保持一份上千个方法的复制,这显然是不科学的,这可肿么办呢,prototype应运而生。