深入学习JS — 原型、原型链、typeof和instanceof的理解

12 篇文章 0 订阅

目录

一、概念

1、所有的引用类型(数组、函数、对象)可以自由扩展属性(除null以外)。也就是说,可以使用Obj.prototype={}来添加新的属性。


2、所有的引用类型都有一个’_ _ proto_ _'属性(也叫隐式原型,它是一个普通的对象)。


3、所有的函数都有一个’prototype’属性(这也叫显式原型,它也是一个普通的对象)。


4、所有引用类型,它的’_ _ proto_ _'属性指向它的构造函数的’prototype’属性。


5、当试图得到一个对象的属性时,如果这个对象本身不存在这个属性,
那么就会去它的’_ _ proto_ _'属性(也就是它的构造函数的’prototype’属性)中去寻找。

二、原型

原型的英文:prototype

function Person(name) {
 this.name = name;
}
Person.prototype = {
 sayHi: function () {
     console.log('Hi , my name is ' + this.name + '!');
 }
}
var yancy = new Person('yancy');

console.log('yancy.__proto__: ',yancy.__proto__);
console.log('Person.prototype: ',Person.prototype);
yancy.sayHi();

在这里插入图片描述

其实[[prototype]]和__proto__意义相同,均表示对象的内部属性,其值指向对象原型。前者在一些书籍、规范中表示一个对象的原型属性,后者则是在浏览器实现中指向对象原型。

如图,yancy对象并没有syaHi方法属性,但是我们给它的构造函数Person添加了sayHi属性,所以它可以直接调用sayHi()。这个sayHi属性是在它的__proto__属性里找到的,更准确的说,是__proto__所指向的Person构造函数的prototype对象属性中定义的sayHi属性,也就是原型中的属性。

为什么要使用原型呢?

不使用原型,只需要在构造函数Person中,直接定义sayHi属性。yancy一样可以直接调用。但是,这样是存在缺陷的,如果我利用Person构造了许多实例对象,那么每个实例对象中都包含了sayHi属性,看似并没有什么不妥。然而,既然这些实例对象中的sayHi属性都是一模一样的,为什么不提取出来呢?
于是js引入了原型的概念。

三、原型链

当前对象调用属性,发现自己没有,便去__proto__也就是构造函数的prototype属性中去找,如果构造函数的prototype属性中没有找到,那么就会去构造函数的prorotype属性(也是对象)的__proto__中(也就是其构造函数的protype属性中找),依次类推,指导找到了Object的__proto__(为null),如果依旧没找到,那么就没有该属性。

在这里插入图片描述
如图:
(1)、如果yancy.sayHi(),则会在Person.prototype中找到sayHi属性并调用。
(2)、如果yancy.toString(),则会在Object.prototype中找到toString属性并调用。

四、typeof和instanceof

(1)、typeof

typeof运算符用于判断对象的类型。
基本用法为 typeof obj


 var number = 1;
 var str = 'Hello World!';
 var array = [];
 var yancy = {
     name : 'yancy',
     age: 20
 }
 console.log(typeof number);
 console.log(typeof str);
 console.log('typeof array: ',typeof array);
 console.log('typeof yancy: ',typeof yancy);

在这里插入图片描述

可以看到,对于数组和对象,typeof的判定结果都为object。
所以不能使用typeof来判断对象是不是数组,那么就需要用到下面的instanceof了。

(2)、instanceof

instanceof相比与typeof来说,instanceof方法要求开发者明确的确认对象为某特定类型。
即instanceof用于判断引用类型属于哪个构造函数的方法。
更重要的一点是 instanceof 可以在继承关系中用来判断一个实例是否属于它的父类型。


var array = [];
console.log('array instanceof Array: ',array instanceof Array);
console.log('array instanceof Object: ',array instanceof Object);

在这里插入图片描述
判断实例对象是否在函数的原型链上:

function Person(name) {
    this.name = name;
}
Person.prototype = {
    sayHi: function () {
        console.log('Hi , my name is ' + this.name + '!');
    }
}
var yancy = new Person('yancy');

在这里插入图片描述
可以看到yancy对象是在构造函数Person原型链上的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值