function 儿子(name, age, isGay) {
this.name = name;
this.age = age;
this.isGay = true;
}
VAR myson = new 儿子('小明', 50, false)
myson.isGay = false
上面的这个就是构造函数,我们也可以叫他为儿子生成器,或者图纸。
我们拿着图纸去生成不同的儿子,儿子你又可以给他新的属性等等~你可以DIY~
是不是很有意思。
好了我们进入正题。
普通对象和函数对象
JavaScript中万物皆对象,但对象之间也是有区别的。分为普通对象和函数对象。
我们大前端是不怕单身的,没对象可以new一个。
在看代码的时候,经常会看到这些东西。
var a = new Object;
var b = new funxtion() {……}
这就是被我们new出来的对象。
很明显,上面的是普通对象,下面的是函数对象。
普通对象如果加上了prototype的属性,那么就变成了原型对象。
每个函数对象创建的时候,都会自带一个prototype的属性,这个属性相当于一个指针,指向他本身的原型对象,这个原型对象里包含着自定义的方法属性。
好了,让我们来实践一下,首先我们要做一只猫咪和一只狗狗。
var miao;
miao.PRototyPE = {
name = "大蛋蛋",
age = 1
}
function dog(name, age){
this.name = name,
this.age = age
}
我们停一下
昨晚在我写到这里的时候,去看了一本书,上面写着其实js的继承,其实并不应该叫继承。
在其他语言中,继承是属于复制。
我创造了一个爸爸,那么继承就是我复制了很多爸爸出来,每个爸爸都一样的。
当然你也可以给你创造的每个爸爸一些单独的属性,这个爸爸会做饭,那个爸爸会钓鱼。
在you don`t know js里面的第五章写着:
本来设计js语言的时候并没有想将它做的太过复杂。
通过new的函数调用并没有创造关联,这个关联只是一个**意外的副作用**。
这个观点我目前还不是太清楚对错,但是我们可以暂时先这么理解一下。
如果说其他语言的继承,就是复制的话,你创造一个爸爸图纸,可以作出不同的爸爸。
那么js的理解应该就是,你创造一个爸爸,并且生出一堆儿子,每个儿子都可以拥有爸爸给孩子的东西,例如钓鱼、做饭(爸爸的方法)。为什么会拥有他的方法呢?
因为在儿子还没有学习这个方法的时候,我们班主任让儿子去钓鱼,那么儿子不会,就会向上查找去叫爸爸,如果爸爸有这个技能,我们就可以成功完成任务了。
现在我们来用做简单的语言来阐述一下原型和原型链。
什么是原型?那就是爸爸。
什么是原型链?那就是爸爸和儿子的关系。
不知道这么解释会不会有点牵强,不过这确实可以有助于我们去实践下一步。
现在开始真正的实践。
我们还是简单去做一个爸爸吧。
function 爸爸(name) {
this.name = name;
this.goFishing = function(fis) {
return fis
}
}
var 儿子小明 = new 爸爸('小明')
儿子小明.name
儿子小明.goFishing('章鱼')
爸爸.prototype.cook = function () {
['米饭', '爆炒鱿鱼', '番茄蛋汤'].foreach(i => console.log(i))
}
儿子小明.cook()
现在我们打印一下小明儿子。
儿子里面有:{name: "小明", goFishing: ƒ}
这是爸爸直接给儿子的东西。
那么爸爸还没给儿子,儿子却可以使用的到哪里去了呢?
我们往下再看,有一个__proto__。
在这里面,就能发现爸爸的cook。
所以爸爸的独门绝技丢在了prototype里面,这里面是儿子不需要学习却可以直接使用的独门绝技~
构造函数属性(constructor)
这个又是什么呢?
其实在刚刚我们打印儿子小明的时候,在cook下面,有一个constructor的东西,就是这玩意。
还是刚刚的代码,现在跟着我一起打印一下儿子小明.constructor。
现在直接把爸爸打印出来了。
这个怎么理解呢……
我找到了一句话。
在默认情况下,所有的原型对象都会自动获得一个 constructor(构造函数)属性,这个属性(是一个指针)指向 prototype 属性所在的函数(Person)
好了,就按照这句话这么理解的话,我们可以理解为:
所有的儿子都会有一个constructor的属性,这个属性指着可以获取爸爸独门绝技(prototype)的那个爸爸。
现在我叫他找爸爸属性……
现在我们再创建一个女儿
var 女儿小花 = new 爸爸('小花')
儿子小明.constructor === 女儿小花.constructor
那我们用了找爸爸属性,所以小明和小花的爸爸是同一个爸爸~
现在我们再仔细看一下刚刚打印出来的小明。
@H_456_
360@敲黑板。
goFishing:ƒ (fis)
name:"小明"
__proto__:{
cook:ƒ ()
constructor:ƒ 爸爸(name)
__proto__:Object
}
仔细看,constructor在哪里~
大声告诉我在哪里~
在__proto__里面对吧。
所以这个找爸爸的属性是从爸爸那里带过来的,是爸爸告诉你怎么找爸爸,并且没有实际教会你怎么找爸爸,是直接调用爸爸的独门绝技找的爸爸~
狂敲黑板!
现在我们再来往下科普一下其他的几个数据类型,再研究其原型。
它是 JavaScript 语言的第七种数据类型,前六种是:undefined、null、布尔值(Boolean)、字符串(String)、数值(Number)、对象(Object)。
还有ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。
我们现在先来玩一下数字。
var 数字 = 12;
console.log(数字.__proto__)
var 数字1 = new Number(12)
数字 == 数字1
数字 === 数字1
在打印数字的proto的时候,瞧我们看到了什么!
Number!
这就是他爸爸!
最后谈一下继承的方法吧。
es6:
Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多。
子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类没有自己的this对象,而是继承父类的this对象,然后对其进行加工。如果不调用super方法,子类就得不到this对象。
es5:
方法一:
子.prototype = new 爸爸()
新建一个爸爸作为孩子的独门绝技~
但是要想为儿子新增属性和方法,必须要在new 爸爸()这样的语句之后执行,不能放到构造器中……
来自原型对象的引用属性是所有实例共享的,创建子类实例时,无法向父类构造函数传参
方法二:
function 儿子(name){
父亲.call(this);
this.name = name || 'Tom';
}
但是这样的话,每个儿子都要绑定爸爸的实例函数的副本,影响性能
方法三:
儿子.prototype = Object.create(爸爸.prototype)
创造一个新爸爸的独门绝技来当儿子的独门绝技~
其实方法有很多,我就不一一举例了。
ECMAScript 继承机制实现
如果对文章有什么间接,欢迎悄悄告诉我~ =333333=
么么哒~
上面我还写了数字和数字1,猜猜看我下一章写的是啥~~~
脚本宝典总结
以上是脚本宝典为你收集整理的2018年3月面试心得《原型、原型链》全部内容,希望文章能够帮你解决2018年3月面试心得《原型、原型链》所遇到的问题。
如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。