深圳幻海软件技术有限公司 欢迎您!

js原型(重点理解)

2023-03-02

网络上很多关于JS原型的理解,写了很多,我也看了很多,但总是云里雾里,很多文章一上来就说Object是一切对象的根对象,这句话非常误导人的思维,后来自己在控制台,自己分析出来了比较好理解的方式,下面我来详细屡屡关于js原型的正确理解方式。主要是理解js中的对象,函数,函数对象,函数实例首先我们来聊聊

  网络上很多关于JS原型的理解,写了很多,我也看了很多,但总是云里雾里,很多文章一上来就说Object是一切对象的根对象,这句话非常误导人的思维,后来自己在控制台,自己分析出来了比较好理解的方式,下面我来详细屡屡关于js原型的正确理解方式。

主要是理解js中的对象,函数,函数对象,函数实例

首先我们来聊聊这四个概念

对象

对象是什么呢,对象就是使用json格式表示的代码块,用这种方式表示js中的对象如下:

{ "name":"runoob", "alexa":10000, "site":null }

JSON 对象使用在大括号 {...} 中书写。

对象可以包含多个 key/value(键/值)对。

key 必须是字符串,value 可以是合法的 JSON 数据类型(字符串, 数字, 对象, 数组, 布尔值或 null)。

key value 中使用冒号 : 分割。

每个 key/value 对使用逗号 , 分割。

函数

函数就是function关键字定义的一段代码块,就是自己定义的看得到的那一块代码,称之为函数,js中内置了一些基础函数比如(Object,Date等等),其实质就是带有构造器constructor的对象,js中可以将一个带有构造器constructor的对象表示为为函数,函数是json对象的变体表现形式

(注意:永远不要忘记js中的对象就是json格式的代码块,函数是这个json格式对象的变体)

如下为Object函数的原型Object.prototype,也是一个json键值对对象:

{
{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
__proto__: null
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()
}

函数有两种作用:一是执行特定功能的代码块,二是构造对象

函数对象

函数对象就是函数的原型,要与函数本身区分开来,比如Date函数的函数对象为Date.prototype,后面我在说特定函数对象的时候都会加上.prototype,因为这个函数原型才真正表述为函数对象

函数实例

函数实例就是通过函数构造器创造的对象,一个函数可以构造出多个不同的但相似的函数实例对象,例如:

function myFunction(a, b) {
return a * b;
}
var x = myFunction (3, 3);
var y = myFunction (4, 3); 
从控制台可以分析出函数实例x,y是函数对象Number的子对象,其_proto_属性指向的是Number.prototype,而不是我们通常认为的x,y为myFunction.prototype的子对象
当然这里也不能绝对,因为函数实例的父对象是不确定的,如下实例
function myFunction2()
{
    console.log('nihao');
}
var z=myFunction2();
var m= new myFunction2();
VM360:3 nihao 
undefined
z
undefined
函数实例z返回的日志为undefined
函数实例m返回的日志为myFunction2 {}
以上可知通过new关键字构造的新对象其父对象才指向其构造函数对象

对象与函数的基本认识

对象的_proto_属性指向的是当前对象的父对象

只有函数有constructorprototype属性

函数中的prototype属性字面意思是原型,指的是当前函数的对象原型,函数只是这个对象原型的变体形式

按照我的理解是这样的,创造js这门语言的时候是定义这是一个面向对象的语言,所有首要任务就是指定对象的格式,就有json对象表示法,然后就是构造执行代码块的结构,即函数 表示法,再就是对象与函数的关联,想象js一切皆为对象,函数的定义本身也是在构造对象,即定义的函数可以表示为带有constructor的对象,这就是函数原型,然后通过函数定义法着手定义根对象就是Object.prototype以及其他的一些内置对象

关于Object与Object.prototype的理解

js中所有的对象继承自Object.prototype这个原型对象,这个原型对象用函数表示就是Object,所以很多文章都Object为根对象,这也没错,因为Object表示的就是根,只是这个根是以函数的形式表示出来,而这个函数的原型就是真正的根对象,即Object.prototype:{…}(这个里我省略了对象中的内容),这个Object.prototype派生了函数对象和普通对象(如Math,JSON等,因为这些对象中没有构造器,可自行在控制台查看),永远不要忘记Object这个函数是通过函数构造器构造出来的函数模样的一块代码,其本质是Object.prototype这个原型,这才是根对象。

Object是一个函数,其属性指针_proto_指向的是函数根对象ƒ () { [native code] },而函数根对象的_proto_则指向Object.prototype,应该有这样的关系:Object._proto_._proto_===Object.prototype;

不过js在_proto_属性后面就不让指针跟踪了,不过我们也可以通过变通的方式来查到,从这里可以看出来:

Object._proto_===Function.prototype  //返回值都为ƒ () { [native code] };

Function.prototype.__proto__=== Object.prototype //返回值为true

Object.prototype._proto_则为null。

以上可以看出,JS中的一切对象都是Object.prototype的子对象,函数根对象ƒ () { [native code] }是Object.prototype的子对象,函数是函数根对象ƒ () { [native code] }的子对象,Object函数也不列外。(注意Function函数是函数根对象的显式函数声明,代表着函数根对象,函数根对象ƒ () { [native code] }是在js运行时已经定义好了的对象)

很多文章都说所有函数都派生自这个Function对象,准确的来说应该是所有函数对象派生自Function.prototype,而Function.prototype就是ƒ () { [native code] },那么问题来了,Object也是函数,那它也是派生自这个对象吗,是的,前面我已经说了,Object在js中写的时候是个函数不是根对象,而这个函数的原型Object.prototype才是真正的根对象,其形式为:这个在函数概念那里已经表述出来了,可以返回去巩固巩固。

关于JS Function函数理解

JS内置对象中,Function函数(注意我这里表述的是函数而不是函数对象,因为Function的函数对象准确来说应该为Function.prototype)较为特殊,这个理解起来就比较困难,因为Function.prototype===Function._proto_,很多人很疑惑为什么会等于,其实这里还缺少了一个重要的信息,那就是ƒ () { [native code] },这个才是根函数对象,这个根函数对象的父对象指向的是Object.prototype这个根对象,这是在js运行时中就已经定义好的,而Function.prototype这个函数对象原型恰好就是这个根函数对象ƒ () { [native code] },而这个Function._proto_这个属性指针恰好就指向了ƒ () { [native code] },这都是在js运行时中定义好了, Function这个函数的作用就是为了创建函数实例的另外一种方法,其父类对象还是Object.Prototype,只是显式定义函数的多一种选择。

 

好了,文章结束,希望对各位有所帮助!