js原型入门

前言

本文主要是根据《head first javascript程序设计》摘抄学习而成,学习采用这本书主要是一位阿里大佬的建议,经过近期的学习阅读,发现确实比其他的js书籍能更好的理解和使用js的相关知识。

对象图

为了更好地理解对象的结构,我们可以向后端学习,做出对象图,它基本是分为三栏的一个矩形图,第一栏是构造函数名称,第二栏是对象具有的属性,第三栏是对象具有的方法。

构造函数的效率

一般情况下,我们是使用构造函数进行一些类定义的,在构造函数中你会定义一些这个对象需要用到的属性或者方法。比如下面的Dog的代码。

function Dog(name,owner){
  this.name = name 
  this.owner = owner
  this.walk = function(){
    console.log("walking")
  }
}

var fido = new Dog("fido","xiaoli")
var fully = new Dog("fully","zhangmou")

重复的方法是问题么

在上述代码执行后,虽然代码层面,各个实例对象的属性以及方法都指定到了新的对象中,但细节发现,其属性是各自不同,可以理解,但是其方法也会都有一个函数的指向,这部分是重复的。那么这里就会涉及到一个内存的问题,因为每个实例对象都创建了自己的方法,重用方法的代码,会占据很多的内存,影响性能(尤其移动端)。

之所以出现这样的问题,是因为我们没有充分利用好js的对象模型,其是基于原型的概念的。

原型是什么

js可以从其他对象那里继承属性和行为,更具体的说js使用原型继承。其中其行为继承的对象称为原型对象。这个是指,会继承原型对象的属性(包括属性方法),同时在新对象中添加属性。

那么如果我们要定义一个小狗的原型,其对象图是什么样的呢?

这里需要注意的是:在小狗的原型中,其定义的属性和属性方法都要求是每个实例必然会用到且基本不会被更改或者重新定义的。

那么它的代码实现会怎么写呢?

Dog.prototype.type = 'animal'
Dog.prototype.bark = function(){
  console.log('barking')
}

继承原型

在有了原型对象之后,我们可以使用虚线来代表继承,发现新小狗实例对象都会通过继承的方式来使用原型对象的属性和方法,而不是重新赋值或者自建私有方法。

继承的工作原理

其继承的工作原理是查找关系: 1 编写代码,比如调用bark()

2 在实例对象中查找方法,没有找到

3 在实例对象中找不到,继续沿着继承链向上寻找

4 在小狗的原型中找到了 方法bark

5 在找到方法之后完成调用

总结:在使用原型继承之后,其会调用同一个bark方法,大量的节省了内存。这样不但能够重用代码,而且能新增属性和行为。

重写原型

那如果有些时候,我们需要重写bark方法,而不用原型中的方法呢?

答案肯定是可以的,我们可以在对象中重新定义自己的属性和方法,那么在继承的工作原理中,他就会现在实例对象中寻找,找到对应的方法之后就不会向上寻找原型对象的方法。

let little = new Dog("little",'xiaoli')
little.bark = function(){
  console.log('self bark')
}
little.bark()

关于this指向

我们之前有讲过,在原型对象中this是指向原型对象的,同样我们也很好理解在没有原型的时候,this调用指向的是对象本身,但是你在调用原型原型的方法时你可能认为this指向的是原型对象,其实并非如此。

调用方法时,this被设置为方法被调用的对象,即便在对象中找不到该方法,在原型中找到了方法,也不会修改其this的指向。

所以其准确的解释是在任何情况下,this指向的都是原始对象,即方法被调用的对象,在原型中也是如此。

我们可以通过代码进行验证:同时,虽然this指向的是原始对象,但并不影响其对原型对象的属性和方法的调用,这就是继承的本身。

Dog.prototype.name = 'default'
Dog.prototype.type = 'animal'
Dog.prototype.bark = function(){
  console.log(this)
  console.log(this.name+' is barking')
  console.log(this.name+' is '+this.type)
}
let little = new Dog("little",'xiaoli')
little.bark()

更多

更多的知识请参考下一篇文章《原型了解进阶》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Java进阶之路

java中hashCode和equals的使用

1430
来自专栏PHP实战技术

解构赋值,你不能不懂!

14510
来自专栏布尔

想起温习一下JS中的this apply call arguments

很多时候讲到语言入门,大家会认为就是要了解一下语言的语法、数据类型和常用函数。这一课对于所有的计算机专业的毕业生来说都可以自学,然而在最近的实践中(带了两个实习...

21310
来自专栏JetpropelledSnake

Python入门之面向对象编程(一)面向对象概念及优点

本文分为如下几个部分 首先说明面向对象是什么,然后结合实际例子说明面向对象的如下几个优点 方便函数管理 数据封装 对象操作 最后总结一下面向对象的好处 概念...

3727
来自专栏诸葛青云的专栏

C语言入门基础学习函数?来看我就告诉你!

在前面我们已经讲过了一些简单的函数,如程序的主函数main()、标准输出函数printf()。在C语言中,大多数功能都是依靠函数来实现的。But,你知道什么是函...

1243
来自专栏达摩兵的技术空间

a>b的那些事

经常会遇到对比两个值大小关系的逻辑,常规的处理中我们都是处理两个数字或者数字类型的字符串。那么这里进行延伸拓展的练习,来避免一些开发中的采坑。

671
来自专栏技术小站

(String)、toString、String.valueOf用法区别(转)

在Java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能。本文将对常用的转换方法进行一个总结。

1132
来自专栏前端黑板报

一个数字截取引发的精度问题(二)

上篇文章只是简单介绍了Number的 toFixed 方法,周末抽时间把 Number 里的一些方法又看了一下,其中有个方法引起我的注意: Number.pro...

1976
来自专栏Python爱好者

Java基础笔记06

1408
来自专栏前端知识分享

第195天:js---函数对象详解(call、apply)

1123

扫码关注云+社区