promise 到 instanceof 到原型链

本文深入讲解JavaScript中的对象、构造函数、原型对象等概念,并详细解释了原型链的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

instance判断是否属于某个对象上的实例

 

原型链: 先从js的对象讲起吧,js中万物皆是对象,分为普通对象和函数对象,Object 、Function 是 JS 自带的函数对象

普通对象,函数对象

普通对象是什么,函数对象是什么

一、普通对象:

var simpleObject = {};
var simpleObject = new Object();
var simpleObject = new f1();

function functionObject (){}; 
var functionObject= function(){};
var functionObject= new Function('str','console.log(str)'); 

console.log(typeof Object); //function 
console.log(typeof Function); //function 

console.log(typeof functionObject); //function 
console.log(typeof functionObject); //function 
console.log(typeof functionObject); //function   

console.log(typeof simpleObject); //object 
console.log(typeof simpleObject); //object 
console.log(typeof simpleObject); //object函数的实例也是object

二、构造函数

function Person(name, age, job) {
 this.name = name;
 this.age = age;
 this.job = job;
 this.sayName = function() { alert(this.name) } 
}
var person1 = new Person('Zaxlct', 28, 'Software Engineer');
var person2 = new Person('Mick', 23, 'Doctor');

 person1和person2都是构造函数Person的实例,这两个实例都有一个constructor(构造函数)属性,这个属性指向构造函数

 console.log(person1.constructor == Person); //true
  console.log(person2.constructor == Person); //true

得出一个结论,实例的构造函数属性指向构造函数

 

三、原型对象

js每当定义一个对象时,对象中都会包含一些预定的属性。其中每一个函数对象都会有一个prototype属性,这个属性指向函数的原型对象,那么原型对象要怎么去理解呢?

function Person() {}
Person.prototype.name = 'Zaxlct';
Person.prototype.age  = 28;
Person.prototype.job  = 'Software Engineer';
Person.prototype.sayName = function() {
  alert(this.name);
}
  
var person1 = new Person();
person1.sayName(); // 'Zaxlct'

var person2 = new Person();
person2.sayName(); // 'Zaxlct'

console.log(person1.sayName == person2.sayName); //true

那什么是原型对象呢?
我们把上面的例子改一改你就会明白了: 

Person.prototype = {
   name:  'Zaxlct',
   age: 28,
   job: 'Software Engineer',
   sayName: function() {
     alert(this.name);
   }
}

其实原型对象就是指一个普通的对象,就是指prototype这个属性,这个属性其实是一个对象

在上面我们给这个原型对象添加了四个属性

name、age、job、sayName

但其实prototype这个属性也有一个默认属性constructor,这个属性是一个指针,指向prototype所在的函数Person

Person.prototype.constructor == Person

 在上面的构造函数中,我们知道实例也有一个构造属性函数,也是指向构造函数

person1.constructor == Person

那我们试着把这两个公式联系起来

person1.constructor == Person
Person.prototype.constructor == Person

person1为什么会有constructor这个名叫构造函数的属性,因为person1是构造函数Person的实例,所以

Person.prototype也是Person的一个实例

我们试着把Person.prototype想象成A,即

 var A = new Person();
 Person.prototype = A;
// 注:上面两行代码只是帮助理解,并不能正常运行

 所以我们得出结论:(原型对象)Person.prototype也是(构造函数)Person的一个实例

不不,这个结论不够严谨的

原型对象其实就是普通对象(但 Function.prototype 除外,它是函数对象,但它很特殊,他没有prototype属性(前面说道函数对象都有prototype属性))。看下面的例子:

 function Person(){};
 console.log(Person.prototype) //Person{}
 console.log(typeof Person.prototype) //Object
 console.log(typeof Function.prototype) // Function,这个特殊
 console.log(typeof Object.prototype) // Object
 console.log(typeof Function.prototype.prototype) //undefined

 

Function.prototype 为什么是函数对象呢?

 var A = new Function ();
 Function.prototype = A;

上文提到凡是通过 new Function( ) 产生的对象都是函数对象。因为 A 是函数对象,所以Function.prototype 是函数对象。

 

四、_proto_

js中创建对象时都会有一个_proto_的内置属性,用于指向创造他的构造函数的原型对象

 根据上面这个连接图,我们能得到:

person1.constructor = Person;
person1._proto_ = Person.prototype;
Person.prototype.constructor = Person;

 

五、构造器

我们试着创建一个对象

var obj = {} 

它等同于下面这样:

var obj = new Object();

obj是构造函数(Object)的一个实例,所以

obj.constructor === Object
obj.__proto__ === Object.prototype

 其实它和上面的构造函数Person差不多,构造函数(Object)本身就是一个函数(即上面说的函数对象)

同理,可以创建对象的构造器不仅仅有 Object,也可以是 Array,Date,Function等。
所以我们也可以构造函数来创建 Array、 Date、Function

var b = new Array();
b.constructor === Array;
b.__proto__ === Array.prototype;

var c = new Date(); 
c.constructor === Date;
c.__proto__ === Date.prototype;

var d = new Function();
d.constructor === Function;
d.__proto__ === Function.prototype;

 

六. 原型链

  1. person1.__proto__ 是什么?
  2. Person.__proto__ 是什么?
  3. Person.prototype.__proto__ 是什么?
  4. Object.__proto__ 是什么?
  5. Object.prototype__proto__ 是什么?

答案:
第一题:
因为 person1.__proto__ === person1 的构造函数.prototype
因为 person1的构造函数 === Person
所以 person1.__proto__ === Person.prototype

第二题:
因为 Person.__proto__ === Person的构造函数.prototype
因为 Person的构造函数 === Function
所以 Person.__proto__ === Function.prototype

第三题:
Person.prototype 是一个普通对象,我们无需关注它有哪些属性,只要记住它是一个普通对象。
因为一个普通对象的构造函数 === Object
所以 Person.prototype.__proto__ === Object.prototype

第四题,参照第二题,因为 Person 和 Object 一样都是构造函数

第五题:
Object.prototype 对象也有proto属性,但它比较特殊,为 null 。因为 null 处于原型链的顶端,这个只能记住。
Object.prototype.__proto__ === null

七. 函数对象 (复习一下前面的知识点)

构造函数的构造函数是Function (所有函数对象(包括自定义的构造函数,比如 function Person(){} )的_proto都指向Function.prototype)

Number.__proto__ === Function.prototype  // true
Number.constructor == Function //true

// 所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身
Object.__proto__ === Function.prototype  // true
Object.constructor == Function // true

// 所有的构造器都来自于Function.prototype,甚至包括根构造器Object及Function自身
Function.__proto__ === Function.prototype // true
Function.constructor == Function //true

JavaScript中有内置(build-in)构造器/对象(Number,String,Boolean,Object,Function,Array,RegExp,Error,Date,Math,JSON,Global,Arguments)共计12个(ES5中新加了JSON),这里列举了可访问的8个构造器。剩下如Global不能直接访问,Arguments仅在函数调用时由JS引擎创建,Math,JSON是以对象形式存在的,无需new。它们的proto是Object.prototype。如下

Math.__proto__ === Object.prototype  // true
Math.construrctor == Object // true

JSON.__proto__ === Object.prototype  // true
JSON.construrctor == Object //true

这说明什么呢?

所有的构造器都来自于 Function.prototype,甚至包括根构造器ObjectFunction自身。所有构造器都继承了·Function.prototype·的属性及方法。如length、call、apply、bind

Function.prototype也是唯一一个typeof XXX.prototype为 functionprototype。其它的构造器的prototype都是一个对象(原因第三节里已经解释过了)。如下(又复习了一遍):

console.log(typeof Function.prototype) // function
console.log(typeof Object.prototype)   // object
console.log(typeof Number.prototype)   // object
console.log(typeof Boolean.prototype)  // object
console.log(typeof String.prototype)   // object
console.log(typeof Array.prototype)    // object
console.log(typeof RegExp.prototype)   // object
console.log(typeof Error.prototype)    // object
console.log(typeof Date.prototype)     // object
console.log(typeof Object.prototype)   // object

噢,上面还提到它是一个空的函数,console.log(Function.prototype) 下看看(留意,下一节会再说一下这个)

知道了所有构造器(含内置及自定义)的__proto__都是Function.prototype,那Function.prototype__proto__是谁呢?
相信都听说过JavaScript中函数也是一等公民,那从哪能体现呢?如下
console.log(Function.prototype.__proto__ === Object.prototype) // true
这说明所有的构造器也都是一个普通 JS 对象,可以给构造器添加/删除属性等。同时它也继承了Object.prototype上的所有方法:toString、valueOf、hasOwnProperty等。(你也应该明白第一句话,第二句话我们下一节继续说,不用挖坑了,还是刚才那个坑;))

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值