关于原型的一些理解,尽可能写的详细一点。

 学了前端一段时间了,对js当时花了不少时间可是随着后面学习框架有些就忘了。如今重新开始记录下重要的知识点。有不少知识也是查阅js高程和别人的博客,所用的一些例子也是引用那些以为颇有表明意义的,在文章最后贴出有关的博客。有错的地方也请你们指出。有些知识深究的话我能力有限,也不知道;因此不少做为一个结论记住就行。javascript

1.首先什么是对象,什么是函数对象。有些地方也叫函数,我查了下函数和函数对象应该是指代的同一个东西,没有区别。首先前端

 var a={"name":"hello"}; 这是一个普通的对象。 function f1(){};    var f2 = function(){}; 这是函数对象。那么函数对象和对象又有什么不一样了。函数有个叫原型的东西是个对象,可是对象没有。这里引入了 prototype 这个属性,那么这个就是原型对象了,固然不是。它是个指针指向原型对象。这里要记住prototype是个指针后面虽然还有继承有关可是先记住是个指针。这里就先说到这里,区别函数对象和对象,以及一个重要属性prototype,对象没这个属性。java

2,那么对象和函数对象又有什么联系了,首先建立一个普通的对象var person = {}或者var 0=new object()。这是个普通的对象,经过这种字面量能够创造不少单个对象。可是会产生大量重复代码,因此有了工厂模式的出现。web

function creatPerson (name, age) { var person = new Object(); person.name = name; person.age = age; person.sayName = function () { alert(this.name); }; return person; 
}

var person1= creatPerson ("tom",29)
 

他能建立一个包含一些信息的person对象,能够屡次调用这个函数。可是却没有解决对象的识别问题(不知道这个对象的类型)。因此以后重头戏来了,有了构造函数,这个知识点就涉及原型了。app

function CreatePerson(name, age, say){ this.name = name; this.age = age; this.say = say; this.should = function(){ console(this.say); } } var person1 = new CreatePerson("","","");

这个函数也很简单,可是和以前的工厂模式有了些区别。这个函数有个很重要的 new 操做符。看一个实例:框架

function Animal(name){ this.name = name; } Animal.color = "black"; Animal.prototype.say = function(){ console.log("I'm " + this.name); }; var cat = new Animal("cat"); console.log( cat.color, //undefine cat.name //cat ); cat.say(); //I'm cat console.log( Animal.name, //Animal Animal.color //back ); Animal.say(); //Animal.say is not a function

这个函数没看答案以前有可能你是不太清楚,可是看了答案你是应该是能得出一些结论的。虽然你可能不知道发生了什么。首先  console.log( Animal.name, //Animal Animal.color //back ); 这个比较简单没什么说的,不懂的函数的name属性能够看下。 cat.color, //undefine 这个是重点,这里看的出来构造出来的实例并无继承到color这个属性,那么就要引入构造函数的工做的模式了。关键的new字符,js高程是这么解释的:函数

1'建立一个新的对象;学习

2'将构造函数做用域赋给新的对象(即this指向新对象);this

3'执行构造函数里面的代码;spa

4'返回新的对象。 

new Animal("cat") = { var obj = {}; obj.__proto__ = Animal.prototype; var result = Animal.call(obj,"cat");
//var result = obj.Animal("cat")。至关于Animal在obj做用域里面运行
return typeof result === 'object'? result : obj; }

这是一个模仿new运行机制的伪代码,这里咱们看到一个新的东西出现了 __proto__  ,先给这个过程看完:obj的__proto__ 指向Animal的原型对象prototype而后你大概懂了

  cat.say(); //I'm cat 以后,在obj对象的执行环境调用Animal函数并传递参数“cat”。 至关于var result = obj.Animal("cat")。 当这句执行完以后,obj便产生了属性name并赋值为"cat"。可能第二个你看的不太明白那你就能够看看call属性,以及this了。这里先不提,后面能够在仔细作下笔记。引入了__proto__ 那么就至关于引入了原型链了,当你实例化一个对象,就会造成一个原型链,他会去找构造函数的prototype,而后逐级向上寻找,其实原型的重点是__proto__ ,我这里将引入一两道例题帮助本身记忆,以及本身的理解。

 var animal = function(){}; var dog = function(){}; animal.price = 2000; dog.prototype = animal; var tidy = new dog(); //tidy.constructor=dog;实例tidy能够经过受权找到它并用以检测本身的构造函数 console.log(dog.price); //undefined console.log(tidy.price); // 2000

1'首先 dog.prototype = animal;这里没有问题的, 咱们能够赋值任何类型的对象到原型上,可是不能赋值原子类型的值, 好比以下代码是无效的: Foo.prototype = 1;

2'将 animal的值赋给dog的原型对象。 console.log(dog.price);针对这句代码。首先是dog本身的自己的函数是没price这个属性的,而后原型上有,可是二者是没有关系的。

3’ 它先经过查找自生,而后再循着__proto__去原型链中寻找,全局中也没有,都没有因此读取不到price这个属性。

    var Animal = function(){};   Animal.prototype.say = function(){ alert("a"); };     Animal.say()   //Animal.say s not a function            

这个简短的例子也是能说明问题的,而后在来看下面这个例子:

 var animal = function(){}; var dog = function(){}; animal.price = 2000; dog.__proto__ = animal; var tidy = new dog(); console.log(dog.price) //2000 console.log(tidy.price) // undefined
1. dog.__proto__ = animal;直接找到 animal,获取值dog.price==2000;
2. tidy.__proto__= dog.prototype;
3.
tidy.__proto__.__proto__ === dog.prototype.__proto__=== Object.prototype;经过这个原型链确实找不到。这里要区别prototype和__proto__

....................................................................................................................................................................................................................................................................

如今还有个constructor。,constructor始终指向建立当前对象的构造函数。

function Person(name,age){ this.name = name; this.age = age; } Person.prototype = { getName:function(){ return this.name; }, getAge:function(){ return this.age; } } var p = new Person("Nicholas",18); console.log(p.constructor); //Object()

这里p.constructor不等于person是由于上面的给她至关于从new成一个新的对象

Person.prototype = new Object({
  getName:function(){
    return this.name;
  },
因此结果是boject。而后如今对new constructor prototype __proto__有了认识以后来讲说原型链。首先是构造函数的原型链。

  构造函数也是有 __proto__属性的,而后也会造成一个原型链。

Constructor ----> Function.prototype ----> Object.prototype ----> null  

 

1,Constructor 的 __proto__ 是 Function.prototype
2,Function.prototype 的 __proto__ 是 Object.prototype
3,Object.prototype 的 __proto__ 是 nullda
答:这个了也只能这么理解,一个函数因为是Function类型,因此它的__proto__是Function.prototype,而Function自己也是个函数(能够new Function嘛),因此Function的__proto__也是Function.prototype。然而而后Function.prototype天然是一个对象,因此Function.prototype的__proto__是Object.prototype。最后指向js的万恶之源null。为何说是万恶之源了,由于才学js就据说万物皆继承于null。
 
而后构造函数的实例又是怎么造成的原型链了,

function f()={};

var obj=new f();

这是一个普通实例的原型的原型链。

 

 还有不少没搞懂的,这部份内容确实多先到这吧,之后在慢慢更新。

相关文章
相关标签/搜索