1. 前言
无意看到了之前整理的高频面试笔记 ,发现很多都有点陌生了,之后我有时间会陆续把一些比较重要的前端知识更新出来。
尤其是现在就业环境不太好的情况下,一方面自己复习巩固下防患于未然,一方面也给小伙伴们的面试助一把力啦
这期依旧是之前整理的高频面试笔记中的题目
2. 普通函数和构造函数有什么区别
这一直是我新手期比较困惑的问题,网上说这个的版本很多,但是都没有让我印象深刻。直到最近翻之前的笔记,好像豁然开朗啦~~~
构造函数是函数的其中一种用法 ,它们的用途不同
js
function test(){}
function Test(){}
let a = new Test()
console.log(test, Test, a)
大家可以看下上图
其实两者的明显区别只有两个
-
用法:被new了之后的是构造函数(构造函数的命名规范是首字母大写)
-
this指向:
-
构造函数中this指向新创建的对象实例
-
普通函数中this指向取决于函数的调用方式
-
构造函数
js
function Person(name, age) {
// 实例属性
this.age = age;
// 实例方法
this.sayHello = function() {
console.log(111);
};
}
// 创建对象实例
const person1 = new Person('Alice', 30);
// 调用实例方法
person1.sayHello();
普通函数
js
// 普通函数
function greet(name) {
console.log(`Hello, ${name}!`);
}
// 调用普通函数
greet('Alice'); // 输出:Hello, Alice!
3. prototype
每个函数都有一个prototype
js
function Person() {
}
// prototype是函数才会有的属性
Person.prototype.name = 'cluonote';
var person1 = new Person();
console.log(person1)
这里,Person 就是⼀个构造函数,我们使⽤ new 创建了⼀个实例对象 person1
那这个函数的prototype 指向的是什么呢?
通俗的说:new 构造函数生成实例的时候,把该构造函数的prototype放到了实例的原型上
通俗的说:该函数的 prototype指向的是实例的原型,也就是person1的原型Person.prototype
(不是person1.prototype,见下图 ),也就是person1.__protoo__
(见下文)
那什么是原型呢?
每个对象(null除外)在创建的时候就会与之关联另⼀个对象,这个对象就是我们所说的原型,每⼀个对象都会从原型"继承"属性。
4. __proto__
那么该怎么表示实例与实例原型,也就是 person 和 Person. prototype 之间的关系呢?
使用__proto__
来表示
这是每⼀个对象(除了 null )都具有的⼀个属性,叫 __proto__
,这个属性会指向该对象的原型。
js
function Person() {
}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true
5. constructor
既然实例对象和构造函数都可以指向原型,那么原型是否有属性指向构造函数或者实例呢
上面这句话划重点了,有点对知识体系承上启下的意思
指向实例没有 ,因为⼀个构造函数可以⽣成多个实例,但是原型指向构造函数是有的 : constructor ,每个原型都有⼀个 constructor 属性指向关联的构造函数
js
function Person() {
}
console.log(Person === Person.prototype.constructor); // true
6. 原型链
当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性 ,如果还查不到,就去找原型的原型,⼀直找到最顶层为⽌。
js
function Person() {
this.age = '18'
}
// prototype是函数才会有的属性
Person.prototype.age = '8';
var person1 = new Person();
console.log(person1)
我们要是找age 的值,首先会到person1.age
(18),假如找不到,会找person1.__proto__.age
(8),假如还找不到,会找Person.prototype.__proto__.age
,假如还找不到,会找Object.prototype.__proto__.age
找到Object.prototype.__proto__
会发现是null
,就会停止查找了,这是最顶层了
person1.__proto__
等于Person.prototype
Person.prototype.__proto__
等于Object.prototype
如下图,蓝色的就是原型链
7. 面试
7.1 说说原型链是什么吧
原型链里面涉及到以下几个知识点:构造函数、prototype
、__proto__
、constructor
和向上溯源
-
每个函数都有一个
prototype
-
构造函数的原型 指向该构造函数的实例对象的原型 ,反过来也OK,构造函数的实例的原型 等于该构造函数的原型
js
function Person() { }
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true
-
礼尚往来 ,构造函数和实例对象都可以指向原型,那么原型的constructor 指向哪里呢?指向其构造函数
-
而原型链:就是找实例对象的属性 ,如果找不到就去找实例对象的原型 里找,再找不到,就去找原型的原型,⼀直找到最顶层为⽌。
-
原型链的顶层 是
Object.prototype.__proto__
,为null
7.2 类的实例对象的__proto__
=== 类的原型吗
等于的
js
console.log(person.__proto__ === Person.prototype); // true
7.3 类本身 === 类的原型的构造函数吗
等于的
js
function Person() { }
console.log(Person === Person.prototype.constructor); // true
参考资料:
9. 总结
原型链算是一个内功心法,工作中常有用到。
其实搞清楚其几个核心概念:构造函数、prototype
、__proto__
、constructor
和向上溯源,基本就算拿下了
这篇文章我尽力把我的笔记和想法放到这了,希望对小伙伴有帮助。
欢迎转载,但请注明来源。
最后,希望小伙伴们给我个免费的点赞,祝大家心想事成,平安喜乐。