JavaScript系列----一切皆是对象

1.判断对象类型

1.1.typeof 运算符

首先要认识到,typepof是一个运算符,其运算须要一个参数,返回值是参数的类型。架构

  •  typeof使用方法  
    typeof  parameter //使用方法1
    typeof (parameter) //使用方法2....这两种方式是等效的。

  • typeof的返回值
      
    typeof的返回值,主要有五种: undefined,boolean,number,string,object.
        JavaScript主要有五种基本数据类型和一种引用数据类型,因此对于typeof的返回值,容易混淆的一点就是下面的一点
    typeof null; //"object”
         null在js中指的是一个空对象。因此,对于typeof null =="object"也是有其道理的。

1.2.instanceof 运算符

  instanceof也是一个运算符,运算过程当中也须要一个参数,判断某一个对象是不是所给的构造函数的一个实例,返回值是true或者false;函数

  •  instanceof使用方法  
 parameter1 instanceof  parameter2 //使用方法 第一个参数是一个对象,第二个参数是一个函数
 parameter1 instanceof (parameter2) //两种方法等效
  • instanceof返回值
     instanceof的返回值,只有两种 true 或者false;
    1.对于基本数据类型,老是返回false;

    console.log(null instanceof Object); //false
    console.log(true instanceof Boolean); //false
    console.log(10 instanceof Number); //false
    console.log("sad" instanceof String); //false

     

    2.对于一个对象,判断其是不是某一个构造函数的实例;
    var object={};
    console.log(object instanceof Object);//true
                
    function A(){}
    console.log(A instanceof Function);//true
    
    var B=function(){};
    var b=new B();
    console.log(b instanceof B);//true

     

1.3.instanceof的原理

   typeof的原理比较简单,主要根据一个其数据类型来返回值。这里咱们主要讲解下instanceof的工做原理.spa

    看下面一道例题:prototype

var Animal = function () {
};
var Dog = function () {
};
//子类继承父类的函数
function extend(subClass, superClass) { var prototype = Object.create(superClass.prototype); subClass.prototype = prototype; subClass.prototype.constructor = subClass; } extend(Dog, Animal); var dog = new Dog();
console.log(dog
instanceof Dog);//true console.log(dog instanceof Animal);//true

 

   上面的这道例子,声明了两个类,动物和狗.用狗类实例化一个对象dog.按咱们的理解,dog固然属于狗这一类,当时,狗难道不是动物吗? 因此上述两种输出结果都输出true.是合理的。设计

  上述代码执行完毕后,内存中的状况大体是这么样的!code

  

知道了内存中的状况,下面咱们来分析一下,代码的执行过程。对象

执行dog instanceoof Dog的时候blog

在判断dog对象是不是Dog类的实例的时候,继承

1.解释器判断dog是不是一个对象,否不是一个对象,则返回false.如果一个对象则跳到第二部。
2.解释器先取得dog的内置属性,而后去取的Dog的函数原型(prototype)。
3.比较dog的内置属性和Dog.prototype是不是同一个对象,如果则返回true.图片

  在执行到第3步的时候,由于则返回true.该句执行结束。

执行dog instanceoof Animal的时候

   按照上述步骤执行到第三部,判断dog的内置属性和Animal.prototype不是一个对象,此时接着执行下一步

4.若dog对象的内置属性和Animal类的原型不是同一个对象,则取出dog的内置属性所指向的对象的内置属性

5.判断dog内置属性所指向对象的内置属性是否和Animal.prototype是否指向同一个对象,如果则返回true.

  不然,沿着对象内置属性链一直向上查找,一直追溯到null(Objece.prototype.__proto__==null)为止。

 简而言之,instanceof比较的时候,

比较的规则是拿对象上的内置属性链上的全部对象与给定的构造函数的原型(prototype)一一比较,直到找到相等的为止。

若比较到最后仍然没有发现二者相等,则返回false.

 

 2.一切皆对象

2.1.为何说,一切皆是对象呢?

 一切皆是对象,这话要从何提及呢!! 看下面的一段代码?

console.log(Function instanceof Object);  //true
function a() {
};
console.log(a instanceof Object);    //true

 

  若是连函数(function)都是对象,以及函数的构造函数(Function)也是对象,那么咱们的确没有理由反对一切皆是对象。可是,怎么证实函数以及函数的构造函数都是对象,这些又是怎么设计的呢?

  咱们知道,若是是对象。那么身为一个对象,就必须具有对象中最基本的一个属性-----内置属性(内置属性是任何对象都有的一个属性),并且,内置属性最初都起源于Object.prototype.若是这么说的话,那么,咱们能够得出一个结论,即 Function和fucntion都具备一个内置属性,且该内置属性直接来自或者间接来自Object.prototype.

 如今咱们用代码来证实一下是否是这个样子:

console.log(Function.__proto__.__proto__==Object.prototype); //true

 

若是这个输出结果是真的,那么在内存中的结构就应该是这么个样子:

 

说道这里,咱们能解释了Function是一个对象。接着咱们来解释function也是一个对象。

一样的道理,function既然是一个对象,那么确定也有内置属性,并且function是Function的一个实例,因此其内置属性确定来源于Function.prototype.那么Function.prototype是什么呢? 

console.log(Function.__proto__==Function.prototype);//true

 

 讲到这里,是否是明白了什么呢?  原来Function的内置属性和其原型属性居然是同一个对象。 好,进行到这里,咱们就来一张综合图来分析一下,function  Function Object.prototype三者间的关系。

 

 到这里咱们算是揭示了一切皆是对象的设计。可是若是想要理解整个设计的架构,咱们还须要搞明白一些事情?

即 从图中咱们看出,

1.Function的对象的内置属性的constructor指向Function.

由于constructor指向Function ==> Function.__proto__是Function的一个实例 ==> Function.__proto__是一个函数。 ok...证实一下:

console.log(typeof Function.__proto__);//function 这里不要用instanceof判断,若是用instanceof判断,返回结果是false.要想查明缘由,请看instanceof工做原理。

 

  到这里也就证实了咱们的推论。可是,下面的一个问题来了,全部的对象都有一个内置属性啊。换句话说,Object函数应该有一个内置的[[_proto_]]属性,而Object.prototype也应该有一个内置的[[_proto_]]属性。ok..上面的这幅图片,若是补充完整的话,结果应该以下所示:

 

   上面这幅图片上,咱们能够看出,不管一个对象的构造函数是谁,其内置属性最终会回归到最上层的Object.prototype.因此,也就是说一切皆是对象,这句话,不仅是说说而已。

注: 上面的这幅图片理解起来不是那么容易。

因此,下面咱们来谈谈,怎么看懂上面那副图片?

2.2.为何要如此设计?

 从美学的角度来讲,上面的那种设计图真的谈不上美观,第一,它不简单,七拐八绕。第二,很难看出来图片想要表现的是什么! 

看懂上面那幅图片,须要有三个最基本的指导思想,

  1.一切皆是对象。 

  2.对象总有一个内置属性,且该内置属性指向其构造函数的prototype属性。

  3.函数总有一个prototype属性,该函数在实例化的实话,该属性赋值给实例的内置属性。

 

明白了上面的三点,下面的几段代码,看看你是否可以回答正确?

 

function a() {};
console.log(a.__proto__ == Function.prototype);
console.log(Function.__proto__ == Function.prototype);
console.log(Function.__proto__.__proto__ == Function.prototype)
console.log(Object.__proto__ == Function.prototype);   //这些代码是为了证实第二点,第一点咱们在2.1中已经证实
function a() {};
console.log(a.__proto__ == Function.prototype);
var object={}; console.log(object.__proto__==Object.prototype) //这些代码是为了证实第三点

  正由于有上述三种知道指导的存在,因此咱们才会使得JS有那么眼花缭乱的效果。

  如今,你按着这三种知道思想来考虑一下,是否有比上张图片更好的设计呢!! 

注: 在JS中,并非严格的面向对象,能够说,一切只是技巧的堆砌。不过,这门语言给人的启发的确能够引人深思----面向对象是否有更好的设计呢?

 

3.总结 

总结的部分,其实就是列出一下这篇文章中写做的重点。

首先,分析下typeof和instanceof的比较,目的是掌握instanceof的工做原理。由于在第二部分中,须要大量使用这个函数。

其次,咱们逐步分析,一切皆是对象这个观点。而后,用实例来证实观点。

再次,证实一切皆是对象以后,接着来分析,用图片一步步引出,整个设计的轮廓,重点是掌握最后一张图片。由于全部的目的       都是为了证实最后一张图片。

最后,提出这种设计的核心指导思想。你能够比照着这种指导思想仔细阅读第二部分。

相关文章
相关标签/搜索