深入分析javascript里对象的创建这个小系列是我整个博客里最受欢迎的文章,有博友催我把下篇写完,昨天和今天整理资料发现一篇文章还真讲不完我下半部分的内容,所以把本来打算写的下篇分成两部分了。
本主题的上篇里我讲到了三种对象创建的方式,最后通过类比java面向对象的思想反过来理解javascript对象的创建。如果根据标题的核心对象的创建,我所阐述的问题其实已经讲完,但是我写完上篇时候总觉得欠缺点啥,欠缺我的标题里面的深入分析二字。小小的创建一个javascript对象它所包含的技术的延伸面是极其宽泛的,到了实际开发时候没有一定发散的知识的积累我们想还会碰到难以理解的问题,中篇和下篇我想从我前一篇讲到的知识拓展开这个问题。
1.类的属性和方法的另一种理解
上篇里面我写到一句话:“一.属于类的属性和方法:用对象初始化的方式都可以当做是属于类的属性和方法,这种定义在jQuery里面大量运用。”
大家知道在java里面类可以具有静态属性和方法,无需实例化该类的对象,就可以访问这些属性和方法,但是javascript里面是不是只有通过对象初始化方式才会模拟出这样的特点了?其实不然,在编程语言里,类的方法和属性比较标准的叫法是:静态作用域定义的属性和方法任何时候都能从同一个位置访问。其实严格意义上说javascript是没有静态作用域,对象初始化可以产生这样的效果,但是它太不直观了,前面的博文里我讲到javascript语言设计时候省略的类这个定义,而是把类的定义赋予到了构造函数里面,那么我们可以这样思考,要想让javascript语言里有属于类的属性和方法,最佳的展现形式就是让构造函数本身具有属性和方法,大家看下面代码:
function JsObj()
{
this.sayHello = function(){
console.log('Hello World!!!');
}
}
JsObj.whosay = function(){
console.log('sharpxiajun say Hello World!!!');
}
JsObj.whosay();
var obj = new JsObj();//sharpxiajun say Hello World!!!
obj.sayHello();//Hello World!!!
这种写法体现类的静态属性和方法特点会更加清晰些,前不久有人告诉我javascript里面的面向对象的做法现在已经成为了一种实现面向对象的标准,有些新语言现在就借鉴javascript来设计自己的面向对象的机制,但是我另可不去相信这个说法,我还是愿意把java的方式作为面向对象的标准方式,而javascript只是用模拟方式来实现,如果真让我把javascript面向对象做为一个新标准来理解,惯性的思维可能很难让我对javascript面向对象的做法有更加清晰的认识。如果说上面代码所运用的原理无非是javascript里面函数就是对象,同样可以为其赋值或者授予方法。这个问题很简单,也很好理解,我这里拿出这段代码是想告诉大家,我在读一些经典框架源码时候,有些设计思想就是运用了这种写法,但是我却没有把他们当作静态变量来理解,导致有些代码没有读懂。
2.关于this指针的问题
这是javascript最最最重要的一个概念,它的用法是掌握javascript精髓的关键。我们先看看下面这句话很关键,它道出了this用法的精髓:
关键字this的用法:它用在对象的方法中,this总是指向调用该方法的对象。
这句话道出了this是存在于对象的方法,里面包含两个内容:对象和方法,方法属于对象,示例格式就是:
var obj = {};//或者var obj = new Object();二者等价
obj.nation = 'China';
obj.say1 = function()
{
console.log(obj.nation);
}
obj.say2 = function()
{
console.log(this.nation);
}
obj.say1();//China
obj.say2();//China
结果一样,这个正好体现了this使用在对象方法中,this总是指向调用该方法的对象。这是对this用法的标准定义,但是真的把这个概念理解透还真的下功夫,下面我抛开这个定义,列举我所知道的this的用法。
用法一:在函数中的使用
function JsObj()
{
this.nation = 'China';
console.log(this.nation);
}
JsObj();//China
那么这个this指向的是JsObj函数吗?回答是NO,this指向的是window,看下面代码:
function JsObj()
{
this.nation = 'China';
console.log(this.nation);
}
JsObj();//China
console.log(nation);//China
console.log(window.nation);//China
console.log(this.nation);//China
看到效果了吧,指向的是window,我想有些童鞋可能不太理解为什么,没关系,这个疑问会引出我下一个小节要讲的内容。
用法二:作为对象方法的调用
这个用法和我最开始讲this指针的用法类似,代码如下:
function say()
{
console.log(this.nation);
}
var obj = {};
obj.nation = 'China';
obj.objSay = say;
obj.objSay();//China
用法三:作为构造函数的调用
说道javascript构造函数,我就要反复再强调一个基础知识:在javascript里的构造函数包含了类的特性。下面看我写的代码:
function JsObj()
{
this.nation = 'China';
}
var obj = new JsObj();
console.log(obj.nation);//China
这个nation绝对不属于window了,大家信不信了?我们可以测试一下:
var nation = 'USA';
function JsObj()
{
this.nation = 'China';
}
var obj = new JsObj();
console.log(obj.nation);//China
console.log(nation);//USA
用法四:apply调用时候的this
apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。测试代码如下:
var nation = 'USA';
function say()
{
console.log(this.nation);
}
var obj = {};
obj.nation = 'China';
obj.objSay = say;
obj.objSay.apply();//USA
obj.objSay.apply(obj);//China
apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为USA,证明this指的是全局对象。apply传入obj对象,this就指向了对象obj了,运行的结果是China。
3.执行环境及作用域
我在上面总结javascript里this用法时候提出了一个问题,为什么this指向了window,解释这个问题就会牵涉出javascript里面有一个非常重要的概念执行环境及作用域。
首先说道的是执行环境,什么是执行环境呢?在javascript里面执行环境分为两类,一类是全局环境,一类是局部环境,整个页面里被共享的方法和属性就是在全局环境,相对于全局环境,函数{}号里的执行环境就是局部环境,执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为,每个执行环境都定义了一个与之相关的变量对象,环境中定义的所有变量和函数都保存在这个对象里,虽然我们自己编写的代码无法访问这个对象,但解析器在处理数据时候后台会使用到它。
全局执行环境另一种说法是最外围的一个执行环境,在web浏览器的范围中(actionscript也是施行了ECMAScript标准,它的全局范围就和javascript的全局范围不同),全局执行环境被认为是window对象,因此全局变量和函数都是作为window对象的方法和属性来创建的,全局执行环境知道应用程序退出比如关闭网页或浏览器才会被销毁。而局部环境则是以函数对象作为关联对象。
javascript语言规定了全局执行环境和局部执行环境的概念,这就产生了一个极其重要的应用:作用域链。当代码在一个环境里面被执行的时候会创建变量的对象构成的作用域链,它的用途是保证对执行环境有权访问所有变量和函数的有序访问。作用域链的前端始终是当前执行代码所在的环境的变量对象。如果这个环境是函数,则将其活动对象作为变量的对象,活动对象在最开始时只包含一个变量,就是arguments对象,arguments在全局环境中是不存在的,作用域链的下一个对象来自包含前一个对象的外部环境,而再下一个变量对象则来自下一个包含环境,如此类推,一直延续到全局环境,全局环境永远是作用域链最后一个对象。
呵呵,看这个解释是不是有点晕啊,我想换个角度思考可能好理解点,在javascript里,所有的属性和方法都是属于某一个对象的,其实在javascript里面,所有方法或属性的调用都是obj.method(),obj.name样式,如果程序代码里调用属性或方法时候找不到这个调用对象,javascript解析器就会往函数作用域的上层作用域里找,直到window全局环境,实在找不到的就默认授予给window对象。
好了,今天内容就写到这么多吧,真没想到javascript一个个看起来简单的对象创建能延伸出这么多知识,回味下这种点到面的研究方法还是蛮不错的,最近做java太多(我最近想开起一个新系列,我一直想做的系列android,不过有人跟我说一个人精力有限,我还是先把没写完的东西写完),写javascrip的激情有点不够了,真希望有一个全职做前端的环境,不过java也是很有趣的,最近和博友交流后我越加有动力把三套javaEE框架写完,给自己打打气,加油了。
相关推荐
课程中的源码分析部分,可能是对一些经典库或框架的源码解读,如jQuery、lodash等,通过阅读源码,可以深入理解JavaScript的高级技巧和优化手段,提升代码质量。 八、笔记总结 笔记部分是对整个学习过程的记录和...
4. JavaScript: JavaScript是网页动态效果的关键,它在客户端运行,处理用户交互。学习JavaScript,你需要掌握变量、函数、对象、DOM操作以及事件处理。JavaScript还有许多库和框架,如jQuery、React和Vue.js,...
在本篇【读书笔记: JavaWeb从入门到精通 第13章: Ajax 技术】中,我们将深入探讨Ajax(Asynchronous JavaScript and XML)技术,它是现代Web开发中不可或缺的一部分,用于实现页面的异步更新,提升用户体验。...
理解这些基础知识是掌握JavaScript的第一步,随着学习的深入,还将涉及DOM操作、事件处理、函数、对象、数组、正则表达式、闭包、异步编程等更多概念。JavaScript的灵活性和广泛应用使其成为Web开发不可或缺的一部分...
在“JavaScript笔记”中,我们可以探讨以下几个关键知识点: 1. **基础语法**:JavaScript的基础包括变量(var、let、const)、数据类型(如字符串、数字、布尔值、null、undefined、对象和数组)、运算符(算术、...
JavaScript是一种广泛应用于网页和互联网应用的脚本语言,它的主要任务是增强用户的交互...通过深入理解JavaScript和Julia,以及如何在Pluto环境中整合这两种语言,开发者可以提升自己的技能,创造出更富创新性的项目。
在"JavaScript基础语法.pdf"文件中,这些内容可能以更详细的形式呈现,包括示例代码、运行结果的截图以及深入的解释和分析。 通过深入学习这些基础语法,你可以逐步建立起JavaScript编程的基本技能,为进阶学习和...
函数是可重复使用的代码块,JavaScript中的函数可以作为值传递,也可以作为对象的方法。对象是键值对的集合,可以使用对象字面量或构造函数创建。理解原型和原型链对于深入学习JavaScript至关重要。 3. **DOM操作*...
另外,"工具"标签可能意味着笔记中会介绍一些开发工具,如浏览器的开发者工具,它们提供调试JavaScript、检查元素、分析性能等功能。还有可能是版本控制工具Git,用于管理代码版本和协作开发。 文件名"javascript....
### JavaScript学习笔记:深入理解鼠标滚轮事件与页面加载事件 #### 鼠标滚轮事件的捕获与控制 在网页开发中,鼠标滚轮事件的处理是提升用户体验的一个重要方面,尤其是在需要平滑滚动或缩放操作的场景下。在给定...
通过分析和修改源代码,学习者可以深入了解JavaScript面向对象编程、事件处理、以及如何用纯JavaScript实现复杂的逻辑。这个项目对于提升JavaScript编程能力,特别是游戏开发方面的能力,具有相当大的价值。
“IJavascript是用于Jupyter笔记本的JavaScript内核”这个主题揭示了一个关键的信息——JavaScript现在...通过深入理解和使用IJavaScript,开发者和分析师可以更好地融合JavaScript和数据分析世界,推动创新和发现。
### JavaScript高级第04天笔记1:正则表达式与网络协议 #### 一、正则表达式的概念与使用 ##### 1.1 正则表达式的定义 正则表达式(Regular Expression)是一种用于匹配字符串中字符组合的工具,在 JavaScript 中...
在前端开发中,让元素在页面上居中是一项常见的任务,尤其对于布局设计至关重要。本篇文章将深入探讨如何使用HTML和JavaScript...通过阅读和分析这些笔记,你可以更深入地理解这些方法,并可能发现其他实用的技巧。
这份名为“JavaScript必看全面总结.zip”的压缩包文件包含了一份深入的JavaScript学习笔记,旨在帮助开发者全面掌握这一动态类型的脚本语言。以下是根据标题和描述提炼出的JavaScript关键知识点: 1. **基础语法**...
在创建对象和数组时,使用直接量(literal)的方法是最快的,尤其是当对象或数组较大时更为明显。延迟加载和条件预加载可以避免不必要的工作,提高性能。 第九章:构建并部署高性能JavaScript应用 为了优化Web应用...
10. **性能优化**:书中还涉及了JavaScript性能优化的技巧,如避免全局查找、减少DOM操作、合理使用缓存等,以及如何使用开发者工具进行性能分析。 通过学习《JavaScript忍者秘籍(第2版)》,读者不仅可以掌握...
这份"学习笔记:年、日、月,周访问量统计"提供了一个实际的案例,帮助我们理解如何收集、分析并解读这些数据。下面,我们将深入探讨相关知识点。 1. **访问量(Page Views)**:访问量是指用户在网站上打开一个...
总的来说,Laverna作为一个JavaScript笔记应用,结合了Markdown编辑器的便利性和本地加密的安全性,为用户提供了私密且高效的笔记管理工具。它的开源特性鼓励了社区参与和创新,有助于软件的持续发展。无论是日常...