《Javascript语言精粹》的学习(一).对象和函数

最近在学习小马和秦歌翻译的《javascript语言精粹》,果然如传闻般,里面的内容博大精深。有些章节所表达的意思往往需要看到后面的章节内容时才能够突然顿悟,因此,称这本书需要反复的去研究,真的名副其实。这两天看了对象和函数这两章,在这里把自己觉得需要关注的内容做一下笔记:

①对象常量中属性名的命名规范

记得刚开始学习对象常量的时候,觉得它真的很简便。一个对象名,一个大括号,N个“名/值”对,OK,搞定!可是在学习的过程中,也遇到过一些疑惑,比如在一些JS书籍中,在写对象常量时,对象中有的属性名用引号引起,有的属性名却没有引号,比如以下的对象常量:

var flight={
 airline:"Oceannic",
 first_name:"li",
 “first-name”:"hu"
}

这应该是比较熟悉的对象常量。可是为何first_name没有引号,而first-name却需要引号呢。以前看过的JS书籍都没有过解释,而我也习惯在写对象常量时,将所有的属性名都用引号括住。在本书中,终于给出了详细解释。在对象字面量中,如果属性名是一个合法的javascript标识符(标识符为首字母为单词,后面选择性加上一个或多个字母,数字或下划线组成)且不是保留字,那么属性名可以不加上引号,初次之外,属性名必须加上引号。本例汇总,first_name和airline是合法的标识符,而first-name不是标识符,所以必须加上引号。

②关于原型

我们都知道,JS的继承方式并不是传统的面向对象,而是面向原型继承的。因此,在JS中,每个对象都会连接到一个原型对象,并从中继承属性。而对象字面量连接到Object.prototype中。这里要注意的是,原型连接在更新时是不起作用的,只有在检索值的时候才会起作用。更新时不起作用就是说对象只能改变它自身包含的属性,而无法改变它连接到的原型链中的属性。检索时起作用是值当对象检索某个属性时,先检查自身有没有该属性,如果没有,再检索它连接到的原型对象,如果原型对象中也没有,再继续检索原型对象的原型对象,也就是顺着原型链查找。

③函数定义中形参的初始化

我们知道,函数的定义通常包括四部分,function,函数名(匿名函数可以省略),形参,花括号。但是JS引擎如何初始化形参的呢。我们知道,在解析函数时,JS一般分为两步:

第一是通过语法分析和预解析构建语法分析树

第二是执行函数,在执行每个函数时会为该函数创建具体的执行环境和活动对象。

具体可见我转载的一篇博文语法作用域与词法作用域。我这里要讲的是,普通的变量在构建语法分析树时就会被初始化,这时它们初始化为undefined(全局变量除外,全局变量直接初始化为它们所赋的值),而函数中的形参却只有在函数调用时才会被初始化为实际提供的参数值。

④蛋疼的this

我们知道,函数既可以当作一个对象的方法来调用,也可以独立调用。当它作为一个对象的方法时,显而易见,它指向的是调用它的对象。但是当它独立调用呢?给出一个例子:

   var flight={
     airline:"Oceanic",
     number:815,
     ‘first-name‘:‘hu‘,
     departure:{
       IATA:"SYD",
       time:"2004-09-22 14:25",
       city:"Sydney"
     }
   }
   flight.double=function(){
     var that=this;
     var helper=function(){
        alert(that==this);
     }
     helper();
   }
   flight.double();

首先我把外层函数的this赋给that,然后在内层函数中将this关键字与that做全等号比较,结果弹出一个打打的false!蛋疼,内层函数中this并没有绑定到外层函数的this,那么它绑定的是什么呢?好,修改一下代码:

   flight.double=function(){
     var that=this;
     var helper=function(){
        alert(window==this);
     }
     helper();
   }
   flight.double();

将this与window做全等,这时候再运行,发现弹出的是true。由此得出结论,当函数独立调用时(这里所属的独立是它既不属于对象的方法,也不是用new来调用),它绑定到的是全局对象。这时候,为了使用外层函数中的this,例子中已经演示,可以在外层函数作用域中定义一个that变量,然后将this的引用赋给它,在内层函数中,可以使用that来访问。

⑤伟大的闭包

习惯上,我们这样去定义一个对象常量:

var myObject={
 value:0,
 increment:function(inc){
    this.value+=typeof inc===‘number‘?inc:1;
 }
}

这是一个很简单的定义。可是哪里似乎有些问题!!不错,安全性,某些时候,我值需要通过increment函数去修改value值,可是,如果这样定义的话,貌似value可以随便更改(myObject.value),这完全违反了我们的初衷,那么该如何修改呢?不错,利用闭包。

var myObject=function(){
  var value=0;
  return{
     increment=function(inc){
        value+=typeof inc===‘number‘?inc:1‘
     }
     getValue:function(){
        return value;
     }
  }
}();

大家再看,这时候,value的值可以如上例中随便更改呢,档案当然是否定的。函数作用域使它只对返回对象中的两个方法可用,对其它程序是不可用的。唉,而myObject的值也不是一个函数,而是匿名函数调用后返回的闭包。唉,闭包真的是伟大!

⑥级联

有用过jquery的童鞋应该知道,为何一个JQUERY对象可以在一条语句中调用那么多的方法呢。不错,用到的正是级联。那么级联的原理是什么呢?我们知道,有一些方法操作型的方法并没有任何返回值,这时候,这些方法返回的undefined,如果我们稍微设置一下,让这些不需要返回值的方法去返回this呢,也就是说在这些方法的末尾加上‘return this‘这么一条语句,不就实现级联了~嘿嘿,下面是我做的一个小demo,相信大家看明白就会理解级联了:

function $(e){
  return new $.fn.init(e);
}
$.fn=$.prototype={
    init:function(){
      var elem=document.getElementById(arguments[0]);
      this[0]=elem;
    },
    width:function(){
      alert(this[0].style.width);
      return this;
    },
    height:function(){
      alert(this[0].style.height);
      return this;
    }
  };
$.fn.init.prototype=$.fn;
$("dv").width().height();
时间: 2024-08-28 08:51:52

《Javascript语言精粹》的学习(一).对象和函数的相关文章

《JavaScript语言精粹》学习笔记

目录: 第一章  精华 第二章  语法 第三章  对象 第四章  函数 第五章  继承 第六章  数组 第七章  正则表达式 第八章  方法 第九章  代码风格   第一章:精华 ····我不过略有一些讨人喜欢的地方而已,怎么会有什么迷人的魔力?    ——威廉 · 莎士比亚 第二章:语法 1.注释: a).注释一定要精确的描述代码,没有用的注释比没有注释更糟糕.   b).javascript提供两种注释方式 /* */ 与  //  ,分别为多行与单行,但多行注释有时是不安全的,比如用某些正

JavaScript语言精粹1字符串,对象字面量

字符串 Strings JavaScript没有,字符,类型.仅包含一个字符的,字符串即可. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>testString1</title> <style type="text/css"></style> </hea

《JavaScript语言精粹》之函数化

写在前面 看到好多书评和读书笔记都说<JavaScript语言精粹>字字珠玑,名不虚传..当然,要看得懂才行 其实个人认为函数化部分不是很好,举的例子不是十分恰当,之前看不懂是因为被成功误导了,就像<Head First>设计模式第一章<策略模式>一样,作者有些偏离章节主题,读者容易被误导 声明:姑且把函数化部分给出的用来创建对象的函数称为“创造函数”吧,为了与“构造函数”区分开..不是很好听,将就着用吧 一.源码中需要注意的点 很容易就能拿到源码,和中文版书上的代码一

JavaScript语言精粹读书笔记- JavaScript对象

JavaScript 对象 除了数字.字符串.布尔值.null.undefined(都不可变)这5种简单类型,其他都是对象. JavaScript中的对象是可变的键控集合(keyed collections). 对象是属性的容器,其中每个属性都拥有名字和值. JavaScript中的对象是无类别的(class-free)的.它对新属性的名字和值没有约束. JavaScript包括一个原型链特性,允许对象继承另一对象的属性. 对象的检索: stooge[“first-name”]或者stooge.

JavaScript语言精粹 笔记01

内容比较简单,只是从头梳理一下JS的知识 语法空白标识符数字字符串语句 对象对象字面量检索更新引用原型反射枚举删除减少全局变量污染  语法 1 空白 空白可能表现为格式化字符或注释的形式.空白通常没有意义,但是偶尔必须用它来分割字符序列,否则它们就会被合并成一个单一的符号.例如: var that = this; var 和that之间的空格是不能去掉的,其他的空格都可以被移除. JS提供两种注释: /* */ // 建议使用//,因为/* */中要注释的内容可能包括字符 */ 而报错,例如:

javascript语言精粹----笔记【转载】

javascript语言精粹----笔记 1.6种值会为假(==false),分别是false,null,undefined,' ',0,NaN 2.typeof有6种值,分别是'number','string','boolean','undefined','function','object';其中typeof(null),结果是'object' 3.number类型总是64位浮点数,两个整数相除也可能出现非整数结果 4.如果第一个运算数的值为假,那么运算符&&产生它的第一个运算数的值.

《javascript语言精粹》——第3章

第三章:对象: 属性名字:可以是包括空字符串在内的任意字符串: 属性值:是除undefined值之外的任何值; [1].对象字面量: var obj={}; //空对象 var newobj={ name:"小明", age:17, school:{ class:"一班" } }; 属性名可加引号,也可不加 [2].检索 newobj["name"] //小明 newobj.age  //17  推荐使用.可读性更加好,紧凑 newobj[&qu

《javascript语言精粹》——第4章函数

函数就是对象 [1].函数字面量即(函数表达式)包括四部分: 第一部分:保留字function: 第二部分:函数名称,可有可无: 第三部分:包围在一对小括号的一组参数,参数用逗号隔开: 第四部分:包围在一对花括号的一组语句,是函数的主体: 函数字面量可以出现在任何允许表达式出现的地方. [2].调用有四种调用模式: 除了声明时定义的形参,每个函数接收附加的的参数:this和arguments  ,this的值取决于调用的模式. 第一种:方法调用模式: var aa={ value:0, incr

JavaScript语言精粹笔记

JavaScript语言精粹笔记 掌握语言的每个特性可以让你出风头,但是并不推荐,因为一部分的特性带来的麻烦可能远超本身的价值.正如书中所言,坏的材料并不能雕刻出好的作品,要成为一名更好的程序员,要取其精华去其糟粕.当你知道要做什么的时候,它还能表现的更好,编程时一件相对困难的事情,绝不应该在懵懂的状态下开始编程之旅. JS中的注意为//或者/*content*/,注释一定要精确地描述代码,不然没有用的注释比没有注释更糟糕. JS中的代码块不会创建新的作用域,因此变量应该被定义在函数的头部,而不