开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第6天
1.构造函数,实例化函数,prototype,proto,constructor,原型对象,Object顶层对象---解析
1.1.构造函数:构造函数与普通函数唯一的区别就是调用方式不同.除此之外,构造函数也是函数.并没有把某个函数定义为构造函数的特殊语法.任何函数只要使用new操作符调用就是构造函数,而不使用new操作符调用的函数就是普通函数.
function person(name,age,sex,old){
this.name=name;
this.age=age;
this.sex=sex;
}
1.2.实例化函数:
//Qin就是实例化对象
var Qin=new person("qinhongyu",21,"男","老");
1.3.prototype属性:
原型:在JavaScript中,每创建一个函数对象,都会天生自带一个prototype属性,这个属性指向函数的原型对象,它默认指向object空对象(Object空对象,没有完美自己创建的属性),称为原型对象。
1.4.原型对象:
原型对象,也就是(构造函数.prototype), 原型对象含有一个constructor属性和__proto__属性,constructor属性(指向的就是当前原型对象的构造函数),__proto__属性指向Object顶层对象(指向其原型链的上一级对象)
1.5.constructor(构造者):
原型对象的构造者即为构造函数
1.6. _ _ proto _ _
指向其原型链上的上一级对象;
比如实例化对象person,其原型链的上一级对象为Person.prototype(person的原型对象)
2.1.原型链核心概念
原型链: 当试图调用或想得到一个对象实例中的属性 或 方法时,如果这个对象本身不存在这个属性 或 方法 也就是说构造函数中没有定义你想要的属性或方法,那么就会通过构造函数的prototype属性到原型中去 寻找这个属性 或者 方法 (也就是它的构造函数的’prototype’属性会到原型对象中去寻找) , 如果有就返回,如果没有就会到顶层的Object去找 , 如果有就返回, 如果还是找不到就返回undefined!
原型链流程图
一个函数的原型链
function a(){}
a.prototype ==>a的原型对象
a.prototype.__proto__ ==> Object的原型对象(Object的顶层对象)
a.prototype.__proto__.__proto__ ==> null
console.log(a.prototype)
所有的函数的原型对象就是Function的实例,所以有prototype
2.2.构造函数、实例化对象、原型对象的基本关系图分析
3.prototype原型
3.1.能够引用prototype的东西绝对是函数,prototype是属于函数的一个属性,
prototype是函数的一个属性,本质是函数的原型对象。
3.2.原型知识点
为了节省内存,我们把对象的方法都放在原型里面。为什么呢?
因为改写对象下面公用的方法或者属性、让公用的方法或者属性在内存中只存在一份
在我们通过new实例化对象的时候,在内存中,会自动拷贝构造函数中的所有属性和方法,用来给实例对象赋值,而不管我们实例化多少次,原型里面的属性和方法只生成一次,所以会节省内存。
3.3.原型对象定义属性或方法优先级比构造函数定义的属性或方法低
- 读取对象的属性值时,会自动到原型链中查找
- 设置对象的属性值时,不会查找原型链,如果当前对象中没有,则直接添加此属性并设置其值
- 方法一般定义在原型中,属性一般通过构造函数定义在对象本身上
function fun(){
}
fun.prototype.a="xxx"
var fn1=new fun()
fn1.a="yyy"
console.log(fn1);
4.instanceof详解
- instanceof是如何判断的?
-
- 表达式 A(实例对象) instanceof B(构造函数)
- 其实就是判断B的原型对象在不在A的隐式原型链上
- 如果B函数的显式原型对象在A对象的原型链上,则返回true,否则返回false
- Function是通过new自己产生的实例
function foo(){}
var f1=new foo();
console.log(f1 instanceof foo); //true
console.log(f1 instanceof Object); //true
console.log(Object instanceof Function);
console.log(Object instanceof Object);
console.log(Function instanceof Function);
console.log(Function instanceof Object);
function Foo(){}
console.log(Object instanceof Foo);
输出为:
true
true
true
true
false
最后一个为false的原因
5.1.面试题
function A(){
}
A.prototype.n=1
var b=new A()
A.prototype={
n:2,
m:3
}
var c=new A()
console.log(b.n); //1
console.log(b.m); //undefined
console.log(c.n); //2
console.log(c.m); //3
一开始b和A存储的都是指向同一个原型对象的地址值,
后面A的原型对象赋值成了一个新的对象,A存储的地址值发生改变,但是b的地址值没变
5.2.面试题2
function F(){}
Object.prototype.a=function(){
console.log("a")
}
Function.prototype.b=function(){
console.log("b")
}
var f=new F()
f.a() //a
f.b() //报错
F.a() //如果f.b()注释,下面分别输出 a和b
F.b()