//构造函数
function Person (name,age,job){
this.name = name
this.age = age
this.job = job
this.sayName = function() {
alert(this.name)
}
}
var person1 = new Person (“张三”,29,“前端”)
var person2 = new Person (“李四”,30,“测试”)
上面的例子中,Person()函数取代了createPerson()函数,构造函数的代码和工厂函数的代码有很大的相似,但是也存在以下不同之处:
-
没有显示的创建对象
-
直接将属性和方法赋给了this对象
-
没有return语句
除了上面的不同外,也要切记以下几点构造函数的特点:
-
构造函数始终都是以一个大写字母开头;
-
创建类的新实例对象,必须使用 new 操作符;
-
创建的不同的实例对象(person1和person2)都有一个constructor属性,改属性指向创建它们的构造函数(Person);即:person1.constructor == Person
-
对象的constructor属性最初是用来标识对象类型的,后来用instanceof操作符检测更靠谱;
创建自定义的构造函数意味着将来可以将它的实例标识为一种特定的类型,而这正是构造函数模式胜过工厂模式的地方;
构造函数模式虽然好用,但是也并非没有缺点,使用构造函数的主要问题就是每个方法都要再每个实例上重新的创建一遍。上面的例子中,person1和person2都有一个名为sayName()的方法,但是两个方法不是同一个Function的实例,不要忘了,js中的函数是对象,因此每定义一个函数,也就是实例化了一个对象,
实例化少量的对象还可以,但是如果要创建上百上万个对象呢,那么sayName()方法也会被重复创建上百上万次,既然上百上万个实例都需要同一个方法,那么能不能实现共享这个方法,只被创建一次,所有实例都能使用,当然有,这个问题就可以通过使用原型模式去解决!
===================================================================
在 JavaScript 中,每当定义一个对象时候,对象中都会包含一些预定义的属性。其中每个函数对象都有一个prototype 属性,这个属性指向函数的原型对象。
重点:每个对象都有 _ proto _ 属性,但只有函数对象才有 prototype 属性
那什么是原型对象呢?
请看下面优化过的代码:
function Person (name,age,job){
this.name = name
this.age = age
this.job = job
}
Person.prototype.sayName = function() {
alert(this.name)
}
var person1 = new Person (“张三”,29,“前端”)
var person2 = new Person (“李四”,30,“测试”)
原型对象的用途是包含可以由特定类型的所有实例共享的属性和方法。上面代码中,person1和person2 两个不同的实例都能访问到sayName方法;
可以结合下图理解:
由上图也可知,只要创建一个函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象;
并且其原型对象都会自动获得一个constructor属性,这个属性是一个指向prototype属性所在函数的指针;
Person.prototype.constructor == Person
其实原型对象也属于实例对象,为什么呢?
person1 为什么有 constructor 属性?那是因为 person1 是 Person 的实例。
那 Person.prototype 为什么有 constructor 属性??同理, Person.prototype 也是Person 的实例。
结论:原型对象(Person.prototype)也是 构造函数(Person)的一个实例;
======================================================================
当调用构造函数创建一个新实例后,高实例对象内部将包含一个指针(内部属性_proto_),指向构造函数的原型对象;
person1.proto == Person.prototype
要明确最重要的一点就是:这个连接存在于实例与构造函数的原型对象之间,而不存在于实例与构造函数之间;
我们可以调用person1.sayName()或者person2.sayName(),虽然这两个实例都不包含这个方法,但是可以通过查找对象属性的过程来实现;其实这就是最简单的一条原型链;
==================================================================
原型链是就是实例对象在查找属性时,如果查找不到,就会沿着__proto__去与对象关联的原型上查找,有则返回,如果找不到,就去找原型的原型,直至查到最顶层Object函数的原型,其原型对象的_proto__已经没有可以指向的上层原型,因此其值为null,返回undefind;
原型链是实现继承的主要方法,其基本思想就是利用原型让一个引用类型继承另一个引用类型的属性和方法;
前面我们已经熟悉了构造函数、原型以及实例的关系,上图所示估计大家都理解了;
可能有的小伙伴说Foo函数与其实例对象的关系我看懂啦,但是它跟Object和Function的关系还是不太清楚,其实我们可以举一反三,他们的关系也离不开上面我们总结的知识点,接下来我们就 一 一 解释 :
为了让你们懂,我还特意在自己画了张图:
首先,函数对象内部有个prototype属性指向其原型对象;原型对象都有一个 constructor属性指向 其构造函数;实例对象内部属性_proto_,指向构造函数的原型对象;也就是下图所示:
然后,每个对象都有 proto 属性;因为函数都是通过new Function()创建的,也相当于算Function函数的实例吧,所以所有函数的_proto_都指向Function函数的原型对象,故Foo()和Objuect()的_proto_属性是指向Function函数的原型对象;而Function函数是通过new自己产生的,所以Function函数的_proto_属性指向自身的原型对象;也就是下图所示:
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容,详细完整版的JavaScript面试题文档,或更多前端资料可以点此处免费获取。
[外链图片转存中…(img-fGElRqAJ-1713780026138)]
最后
[外链图片转存中…(img-MDibJXdh-1713780026138)]
[外链图片转存中…(img-QmJDytwP-1713780026138)]
由于文档内容过多,为了避免影响到大家的阅读体验,在此只以截图展示部分内容,详细完整版的JavaScript面试题文档,或更多前端资料可以点此处免费获取。