JavaScript之原型与原型链【一】

看完此篇文章你将了解到如下内容:前端

一、什么是函数对象和普通对象,以及二者的关联与异同

二、什么是原型以及原型对象是什么?用原型的目的

三、什么是原型链,以及使用场景
复制代码

1、函数对象和普通对象数据库

在全部的编程语言中,万物皆对象,JavaScript也毫无例外.在JavaScript中分为函数对象和普通对象.Function【函数对象】、Object【普通对象】为JavaScript自带的对象.先从几个例子开始入手,看下浏览器打印的结果是什么:编程

function foo(){}
    var foo1=function(){}
    var foo2=new Function()
    
    var obj={}
    var obj1=new foo()
    var obj2=new Object()
    
    typeof Function //function
    typeof Object // function
    
    typeof foo //function
    typeof foo1 //function
    typeof foo2 //function
    
    typeof obj // object
    typeof obj1 // object
    typeof obj2 // object
复制代码

从以上例子能够看出,所谓函数对象,都是经过new Function()建立的.反过来讲,凡是通new Function()建立的对象都是函数对象.除此以外,就都是普通对象.不难看出,foo,foo1,foo2,Function,Object都是函数对象.obj,obj1,obj2都为普通对象.原型对象就是个普通对象,下面咱们来了解下什么是原型对象...

2、原型对象后端

在JavaScript中,每当定义一个函数对象,对象中都会包含一些预约义的属性,其中函数对象的一个属性就是原型对象【prototype】,看个例子:浏览器

function Fn(){}
console.log(Fn.prototype) //Fn{}
console.log(typeof Fn.prototype) //Object
console.log(typeof Function.prototype) // Function 是个特殊的函数,由于Function是被new Function()出来的
console.log(typeof Object.prototype) // Object
console.log(typeof Function.prototype.prototype) //undefined
复制代码

经过上面的例子能够看出:Fn.prototype中的prototype是个隐藏的属性,咱们在浏览器打印发现Fn.prototype这个原型对象中包含一个构造函数(constructor)和一个__proto__属性,从console.log(Fn.prototype) //Fn{}能够看出,Fn.prototype为Fn的实例对象.在Fn建立时,建立了它的实例并赋值给它的prototype,过程基本是这样的:bash

let fn = new Fn();
Fn.protetype =fn;
复制代码

经过上面的过程分析,基本知道为何Function.prototype是函数对象而不是普通对象了,看下面:编程语言

let fn = new Function();
Function.prototype = fn;
复制代码

由于Function.prototype是Function的实例对象,而Function又是函数对象,因此Function.prototype为函数对象.函数

知道了原型对象是什么,下面来讲下原型对象的用处.
原型对象,在JavaScript中主要目的是为了实现继承.【插曲:在Java或C类语言中,面向对象编程是个很好的编程思想,愈来愈多人从过程编程转向了面向对象编程中,它容许咱们把任何事物均可以当作对象去处理,简化了编程的复杂度、代码的易维护性、调测的便利性以及预编译的支持大大下降了程序的响应成本,其中面向对象--封装、继承、多态,就有一项叫继承,由于JavaScript最初就被定义是个弱类型的语言,因此决定它很难像后端语言那样实现复杂的面向对象,但随着前端需求和业务的愈来愈复杂,急需相似后端面向对象的支持。这时候原型对象出现了,模仿类(class)的实现,以及经过原型链来实现继承】(注:在 ES2015/ES6 中引 入了class关键字,但只是语法糖,JavaScript 仍然是基于原型的[prototype]) 来看个原型对象继承的例子:post

function Fruit(type){
    this.type=type;
}
Fruit.prototype.getCategory=function(){
    return this.type;
}
let ty = new Fruit('苹果');
ty.getCategory(); //苹果
console.log('Fruit type==='+ty.getCategory());//Fruit type===苹果
复制代码

从例子中看出,给原型对象Fruit.prototype设置了属性getCategory,在由Fruit实例化出来的普通对象【例:type】属性值就被继承过来了,如何实现继承的,下面就要看下原型链了...ui

3、原型链

JavaScript中,当建立一个对象时,都会有一个内置的__proto__属性,这个属性指向建立它的函数对象的原型对象prototype,下面看下例子:

function Fruit(type){
    this.type=type;
}
Fruit.prototype.getCategory=function(){
    return this.type;
}
let ty = new Fruit('苹果');
ty.getCategory(); //苹果
console.log('Fruit type==='+ty.getCategory());//Fruit type===苹果

console.log(ty.__proto__===Fruit.prototype);//true
console.log(Fruit.prototype.__proto__===Object.prototype);//true
console.log(Object.prototype.__proto__);//null
复制代码

以上过程梳理一下:

一、普通函数:ty为Fruit的实例化对象,这个ty里有个内部函数属性__proto__这个属性指向建立它的Fruit(函数对象)的原型对象prototype
二、普通对象:Fruit.prototype内也有一个内部属性__proto__指向建立它的Object((函数对象)的原型对象prototype
三、普通对象:Object.prototype内也有一个内部属性__proto__但这个属性比较特殊结果为null;
四、以上过程就是一个原型链,咱们把这个以__proto__属性串联起来的直到Object.prototype.__proto__为null时的链,叫原型链
复制代码

若是你有一些关系型数据库基础的话,咱们也能够把__proto__当作是外键,prototype为主键,对象和对象之间看作是一张张表,咱们把主外键关联起来,就造成了一个链,这样理解起来较容易

下面咱们用一张图,来表示这个过程:

JavaScript之浅复制与深复制【二】

欢迎关注,【前端突击】 猎鹰突击,迎难而上,期待你的加入...

相关文章
相关标签/搜索