本文主要记录在学习Javascript(为了减少打字的工作量和读的顺口,以后会使用JS)的过程中,对于“var o = new Obj(1);”这行代码的理解。
在学习和使用JS之前,我学习过一些经典的编程语言,如Java、PHP和C,我可以熟练的使用Java,能够阅读和简单地编写C和C++的代码。
但是当我带着这些经验来接触JS的时候,我发现事情完全变化了,我在很长一段时间内只能用JS实现页面的功能,但是对于类以及类的实例化完全摸不到头脑。
我想这种错误产生于两个原因:
对于JS的学习,我是边工作边学习的,这样学的好处是上手快,缺点也同样显著:基础知识一塌糊涂;
很多JS的知识来源于互联网,网上有很多人自己也是一知半解(当然也包括本文和本文的作者),我看完之后再加上自己的理解,于是我距离真相越来越远了。
言归正传,要理解var o = new Obj(1);,我们首先要知道这条语句是干嘛的?
有过面向对象学习经验的人一定了解,这条语句是类的实例化。
一、要有类和实例化的知识
那么,什么是类,什么又是实例化?
维基百科给了一个比较抽象的定义:类的更严格的定义是由某种特定的元数据所组成的内聚的包。它描述了一些对象的行为规则,而这些对象就被称为该类的实例。
说的具体一些,类就是一些有相同个体的特征抽象,而逆着抽象,从而建立类到个体的过程叫做实例化。
比如中国人就可以作为一个类,每个人中国人都有一个中文名字,这就是类的一个属性。中国人的名字是什么,我们是说不出来的,但作为一个中国人的实例,我的名字是“山谷”。
这是很浅显的知识,尤其是对于计算机知识扎实的人。
二、JS中如何创造类
那么我们来看一段JS代码,JS是如何建立一个类。
var Obj = function(x) {
this.x = x;
console.log(this.x);
//xxxxxxx
};
这是很标准的写法(包括缩进为4个空格而不是一个tab,每行结尾处都没有空格),的确,在JS中,一个Obj的类,就诞生了。
对于没接触过编程的小白还好办,我就这么记忆了,但是有Java或者C++书写经历的人一定会疯掉的,这是函数的声明方法,是的,在JavaScript 2.0之前,JS里面没有“类”(此话是David Flanagan在《JavaScript权威声明》中说的,我特此发表免责声明,由于他在好几个版本都保留了这句话,我假定这句话是真的)。
JS只有“伪类”,没有任何一个JS的结构是类(我们有对象,我们有数组,我们还有函数,我们就是没有类),但是JS可以模仿类,即类有什么,我们就有什么。
那么,类有什么?
类有属性(public、protected、private都行),类还有方法(不管静态的还是动态的),一般情况下,类还有构造函数。
仅以Java为例,我们写一个类看看吧。
public class Obj {
public int i = 0;//属性
private int x = 1;//属性
public Obj(x) { //构造函数
this.x = x;
}
public int getX() { //方法
return this.x;
}
}
那么JavaScript都可以模仿。
首先说JavaScript的构造函数,就是Obj这个function(用英文方便上下文对照)。
那么属性和方法可以怎么办,我们会尝试Obj.xxx这个方式,但事实证明,当var o = new Obj(),o是无法调用xxx的。
带着问题(问题是方法和属性挂载的位置),我们开始实例化吧!
三、实例化总共分三步(和把大象装到冰箱里的步骤一样多)
第一步:var o = {};
第二步:o.__proto__ = Obj.prtotype;//Obj.prototype?我们并没有声明prototype,对,这是浏览器自动加入的。
第三步:Obj.call(o, 1, 2);
总结为:第一步,创建一个空对象并赋值给o;第二步是定义原型链使得o指向Obj的原型对象;第三部为用对象o调用Obj函数,调用参数为1和2。
第一步好理解,既然是实例化,就要实例化类为对象,则o必然是一个对象,先赋值成对象,再进行操作。
第二步的难点在于什么是原型链,为什么原型链要o指向Obj的原型对象,那么Obj的原型对象又是什么?
第三步相对于第二步好理解,唯一的一点是call究竟干了什么?
3.1 原型链
根据ECMAScript的解释:每个由构造器创建的对象,都有一个隐式引用 ( 叫做对象的原型 ) 链接到构造器的“prototype”属性值。再者,原型可能有一个非空 (non-null) 隐式引用链接到它自己的原型,以此类推,这叫做原型链。
o.__proto__指向的是o原型链的上级,而其上级的__proto__由指向上级的上级,当使用对象o的一个方法时,如o.xx,js的解析器会沿着o的原型链一直向上寻找,找到最近的一个xx方法,然后调用。
通俗讲,就是通过这个方式,o可以调用Obj原型上的方法。
值得强调的是,o.__proto__并不具有通用性,目前Chrome、Firefox和Safari支持这一属性。
3.2 原型对象
原型对象也可以叫做原型。ECMAScript的定义很简单: 为其他对象提供共享属性的对象。
就JS的类来讲,原型可以理解为挂载变量和方法的容器。
譬如,我们希望在Obj类中添加getS的方法,常规写法是:
Obj.prototype.getS = function() {
//xxxxxxxxxxx;
};
但是为了方便长时间使用Java和C++的人理解,我们也可以写为:
Obj.prototype = {
getS: function() {
//xxxxxxxxxxxxxxxxxxx;
}
}
3.3 o.__proto__ = Obj.prototype
理解了2.1和2.2,我们就明白了o.__proto__ = Obj.prototype是干嘛的了。
第二步是使Obj上的方法和变量可以为o所用。
3.4 第三步的重点: Obj.call(o, 1, 2)
如果有面向对象的知识的话,可以推出知道,这一步要执行Obj的构造函数。
的确,这一步是由call方法完成的。
那么,call是做什么的?
若有A.call(B, C),则是对象B使用参数C执行A方法,如果你这么回答,似乎是正确的。但我们要向更深处走一步:在执行完call之后,对于A、B、C分别有什么影响。
首先很好理解的是A和C,A使用了C参数,执行了自己,那为什么不直接写A(C),就是为了酷吗?
答案时否定的,若A中有关于this的修改,则this不再指向A原来所在的域,而是指向B。
如下所示:
var A = function(C) { C++; console.log(C); };
var B = {D: 2};
var C = 1;
var D = 1;
这时A.call(B, C);和A(C);是没有区别的。
但是如果A的实现如下所示。
var A = function() { console.log(this.D + C); }
A.call(B, C)的结果就是输出3,而A(C)的结果就是2。
理解了call,我们就能明白Obj.call(o, 1, 2)是做什么的了。
函数Obj(也是类Obj的构造函数),得到了两个输入1和2,再将这两个值赋值给this.x和this.y,最后,将this指向o。
可以思考的问题是为什么属性和方法要挂接到Obj.prototype而不是Obj上?
以上是一些非常肤浅的理解,要解答原型链和原型的很多问题,是需要了解JS的发展历史和浏览器的内核实现,但就工程本身,理解到这里应该可以应付大部分关于类和声明开发了(当然你还有JS的语法知识和算法知识)。
相关推荐
HTML+CSS+JavaScript教程学习笔记HTML+CSS+JavaScript教程学习笔记 HTML+CSS+JavaScript教程学习笔记HTML+CSS+JavaScript教程学习笔记 HTML+CSS+JavaScript教程学习笔记HTML+CSS+JavaScript教程学习笔记 ...
### JavaScript面向对象基础 #### 创建对象 在JavaScript中,创建对象是进行面向对象编程的基础之一。不同于C#等其他语言,JavaScript提供了多种方式来创建对象。最常见的方式是使用`new Object()`或直接通过对象...
JavaScript基础知识点总结 JavaScript是一种高级的、动态的、基于对象的客户端脚本语言。它是在网页上执行的脚本语言,能实现网页的交互功能。下面是该资源中的重要知识点总结: 一、 JavaScript 基本概念 * ...
本学习笔记将深入探讨JavaScript的核心概念,包括变量、数据类型、操作符、控制流程、函数、对象、数组、原型链、闭包等,并结合实际示例,如my.js、order.js、login.js等文件,来讲解其在实际项目中的应用。...
这份“javascript学习笔记整理知识点整理”是针对初学者的一份宝贵资料,涵盖了JavaScript的基础知识,旨在帮助新手快速入门并掌握这门语言的核心概念。 一、变量与数据类型 在JavaScript中,变量用于存储数据。...
Javascript学习笔记PPTJavascript学习笔记PPTJavascript学习笔记PPTJavascript学习笔记PPTJavascript学习笔记PPTJavascript学习笔记PPTJavascript学习笔记PPTJavascript学习笔记PPTJavascript学习笔记PPTJavascript...
JavaScript学习笔记讲解版参考.pdf是一份详尽的教程,涵盖了从基础到进阶的JavaScript知识。这份笔记首先从CSS样式表开始,引导读者理解网页样式的设置与应用。 1. CSS(Cascading Style Sheets)样式表是用于控制...
<a href="javascript:prompt('What is your name?')">Click ``` - **解释:** 用户点击链接后会弹出一个输入对话框让用户输入名字。 ### JavaScript与DOM操作 JavaScript可以用来动态地修改文档对象模型(DOM),...
前端学习笔记网站(HTML5+CSS3+JavaScript前端网页web课程设计).rar前端学习笔记网站(HTML5+CSS3+JavaScript前端网页web课程设计).rar前端学习笔记网站(HTML5+CSS3+JavaScript前端网页web课程设计).rar ...
根据提供的文件信息,可以看出这份“我的javascript学习笔记”主要涵盖了JavaScript中的几个关键概念和技术要点,包括正则表达式、AJAX以及一些JavaScript的核心语言特性。接下来将这些知识点进行详细的整理和解释。...
《javascript高级编程》学习笔记
"Javascript学习笔记(传智播客视频学习笔记+代码)"是一份全面介绍JavaScript基础知识的学习资源,适用于初学者。这份笔记结合了传智播客的web前端培训视频内容,提供了丰富的理论讲解和实践代码,帮助读者从零开始...
从菜鸟教程上学习的关于js的学习笔记,可以用于参考学习使用,脑图样式,浏览更方便,有需要的同学可以带走
JavaScript入门学习笔记
"前端学习笔记-黑马程序员JS" ...这篇前端学习笔记涵盖了 JavaScript 的基础知识,包括变量、数据类型、运算符、流程控制、数组、函数、对象、内置对象和 Web APIs 等知识点,为学习 JavaScript 提供了系统的指导。
这篇"JavaScript入门新手学习笔记"提供了全面的学习资源,适合初学者系统性地掌握这一技术。 笔记可能包含了以下关键知识点: 1. **基础语法**:JS的基础包括变量(var、let、const)、数据类型(如字符串、数字、...
Javascript学习笔记_自学实用 原创笔记,整理得很不错,适合初学者,推荐大家!
文档库,学习笔记,包括但不限于HTML、CSS、JavaScript 文档库,学习笔记,包括但不限于HTML、CSS、JavaScript 文档库,学习笔记,包括但不限于HTML、CSS、JavaScript 文档库,学习笔记,包括但不限于HTML、CSS、...