美文网首页
JS中的对象、类、原型和原型链,以及.prototype和.__

JS中的对象、类、原型和原型链,以及.prototype和.__

作者: HunterHu | 来源:发表于2017-06-28 22:57 被阅读0次

对象、类和原型

在JS中,万物皆对象,对象因为你的“关注”而产生。每个对象都有自己的属性特征和行为方法,函数、数组、对象等都可以被视为对象,那么js中的对象又是怎么产生的呢?

其他大型语言里,对象都和“类”这个概念紧密相连,“类”是对象的一个抽象概念,每个对象都是通过个“类”的构造方法创建的。而js中抛弃了“类”的概念,引入另外一个抽象概念——“原型”。js中每个对象都有一个原型,原型也是对象,所以原型也有自己的原型对象,如果一路找上去,最终会找到Object。也就是说js中所有对象都是由Object克隆出来的,Object是所有对象的起始。

创建对象的方法

1.构造函数

let Construct=function(name,age){
    this.name=name;
    this.age=age;
};
let c1=new Construct("123",123);

通过函数Construct,来创建一个实例对象c1,函数Construct也可称为构造函数。构造函数就是普通函数,只不过通过这个函数new了一个实例对象。在new的过程中通过构造函数的函数体,给对象c1增加了属性。

2.构造函数加原型

let Construct=function(name,age){
    this.name=name;
    this.age=age;
};
Construct.prototype.fn=function(){
    console.log("hello world");
};
let c1=new Construct("123",123);
c1.fn();

在构造函数的基础上,给构造函数的原型(Constructor.prototype)加一个方法fn,将该方法从构造函数的原型(Constructor.prototype)复制到新实例对象c1的原型(c1.__ prototype __ )上。很多人会认为这两个是一个东西,我不这么认为,我理解为每一个对象都有一个自己的原型,下文会详细解释。这样构造函数原型中的方法就会被复制到c1的原型上,c1在自身中找不到fn这个方法,就会去自己的原型:c1.__ prototype __ 上去找。

3.JSON

let c1={
    "name":"123",
    "age":123,
    "fn":function(){
        console.log("hello world");
    },
};
c1.fn();

JSON是js创建对象的一个简便算法,但也有它的缺点,在需要创建的对象数量很多时就不适用。构造函数创建的c1也有一个原型,这个原型为空,可以通过.__ prototype __ 给它的原型添加属性和方法。

4.class

class Construct{
    constructor(name,age){
        this.name=name;
        this.age=age;
    }
    fn(){
        console.log("hello world");
    }
}
let c1=new Construct();

先创建一个Construct的类,在通过new创建一个新的实例对象c1。在Construct这个类中,有一个名为constructor的函数,它可以把里面的属性通过new的过程初始化给c1;还有一个名为fn的方法,这个方法被直接添加到Construct的原型(Construct.prototype)上,在new的过程中又被复制到了c1的原型(c1.__ prototype __)上,所以c1本身没有这个方法,却可以通过原型链调用这个方法。

js的class是es6新增的一个概念,class的提出让我们在创建对象时的逻辑和操作更偏向于面向对象的语言。但它不是一个“真类”,是用函数模拟出来的一个“类”,底层和java等语言还是有很大的差别。

原型链

对象可以通过 .__ proto __ 这个方法找到该对象的原型,有一个特殊的对象——函数,函数通过.prototype找到该函数的原型对象,.prototype这个方法只有函数才可以调用,而找到的是原型对象,所以不能继续用.prototype这个方法。而.__ proto __ 这个方法可以重复调用,通过.__ proto . __ proto __ 来找到最顶层的原型对象Object,这条线就称为原型链。

1.jpg
不管是函数的原型还是实例对象的原型.
proto __后都找到Object,也就是{}

原型对象

let Construct=function(name,age){
    this.name=name;
    this.age=age;
};
Construct.prototype.fn=function(){
    console.log("hello world");
};
let c1=new Construct("123",123);

Construct这个构造函数(也可视为对象)在我们声明的时候,就已经产生了一个原型对象
(Construct.prototype),通过原型对象添加的方法给上面加入方法fn,然后我们通过Construct,new一个新对象c1,要理解原型对象,首先我们要理解new的这个过程,new的过程一共分为3步:

  1. 先通过构造函数Construct来新建一个实例c1,并新建一个c1的原型对象:c1.__ prototype __ (此时,c1和c1.__ prototype __ 都是空的)。
  2. c1.__ prototype __ = Construct.prototype(把Construct.prototype上的方法fn赋到c1.__ prototype __ 上,此时c1还是空的,c1.__ prototype __ 上有了一个方法fn)
  3. 通过函数Construct的函数体,对c1进行初始化设置,将属性和属性值赋给c1。

到此三步结束,c1中具有了属性和属性值,c1的原型(c1.__ prototype __ )上有了fn这个方法,函数Construct的原型(Construct.prototype)没有改变,并且每次new对象的时候,都会重复上述的三个动作。可以通过分别查看c1、 c1. __ prototype __、Construct.prototype来验证刚才的证明。

并且我们在使用原型添加方法的时候,如果通过c1. __ prototype __ 来添加的属性和方法,并不会影响Construct.prototype里的内容,也不会影响其他新new出来的实例对象,只会改变c1自己的原型。而通过Construct.prototype去修改的原型,会影响其他新new出来的实例对象,这更好地解释了刚才的想法。

相关文章

  • 原型和原型链的简单理解

    原型 在JS中原型就是prototype对象,用来表示类型之间的关系。 原型链 JS中对象和对象之间是有联系的,通...

  • js基础(三)

    js基础 原型链和原型对象 ... ... js没有继承原型对象prototype通常用来添加公共的属性或行为且只...

  • JS中的对象、类、原型和原型链,以及.prototype和.__

    对象、类和原型 在JS中,万物皆对象,对象因为你的“关注”而产生。每个对象都有自己的属性特征和行为方法,函数、数组...

  • js基础知识(二)

    一、js原型和原型链 1、原型讲解: 普通的对象:是没有prototype属性的,只有隐藏属性__proto__,...

  • 原型链以及继承

    原型链 原型链类似关系链,几乎所有的js对象都会有通过原型链prototype继承过来的方法或者属性,在java和...

  • 1.原型和原型链-作用域和作用域链

    一、请谈谈原型和原型链 原型js中每个函数都有一个属性,prototype,这个属性的属性值是一个对象,这个对象被...

  • 3-javascript 构造函数

    js中面向对象编程是基于构造函数(consstructor)和原型链(prototype)的。 构造函数作为对象的...

  • 2022前端高频面试题

    JS相关 1.原型和原型链是什么 原型和原型链都是来源于对象而服务于对象的概念js中引用类型都是对象,对象就是属性...

  • JavaScript进阶:原型模式

    1、前言 原型模式是指的将原型对象指向创建对象的类,使得不同的类共享原型对象的方法和属性。js中基于原型链的继承的...

  • js中call、apply和bind到底有什么区别?

    介绍 在js中,每个函数的原型都指向Function.prototype对象(js基于原型链的继承)。因此,每个函...

网友评论

      本文标题:JS中的对象、类、原型和原型链,以及.prototype和.__

      本文链接:https://www.haomeiwen.com/subject/zxupcxtx.html