《JAVASCRIPT:THE COMPLETE REFERENCE》读书笔记 函数与对象

时间:2021-01-01 16:09:27

《JAVASCRIPT:THE COMPLETE REFERENCE》读书笔记 函数与对象

函数

  • 函数声明的基本方法在上文中已经提到。
  • 在JS中函数的提前引用是不被允许的,需要先定义后引用。
  • 参数传递时,5种基本类型通过值传递(创建副本),3种复杂类型通过引用传递,这意味着你可以在你的函数域内对这些值进行修改。如果你需要修改基本类型,请不要将它填写在参数表中传递进函数,而是直接在函数中改写它的值。
  • 当调用期望参数的函数时,如果你没有填写,或没有按照规定填写,空余的部分会被当成undefined数据传递进函数。
  • 在命名时,往往在全局变量前加g。
  • 局部函数被隐藏在函数对象的内部,无法被外部调用。者提供了一种编写独立代码模块的途径。具体写法是:
function testFunction(){
function inner(){};
};
testFunction();//true
inner();//false
testFunction.inner();//false
  • 上述写法是不将局部函数返回的,如果尝试将局部函数通过return返回,就形成了闭包。这个函数将作为父函数的一个方法来实现。
function testFunction(){
function inner1(){}
function inner2(){}
return set:inner1
get:inner2;
}
testFunctiion.set();//访问inner1函数
testFunctiion.get();//访问inner2函数
  • 在函数构造法中,new Function法会消耗更多的内存资源。
  • 匿名函数是那些一次性的函数,不需要赋予变量去调用。往往会将其作为一个函数参数去传递进另一个函数,通过匿名函数的return对参数进行一定的预处理。
  • 在函数中可以定义静态变量,他在父函数所在域中保有内存,对他的修改会保存下来:关于静态属性/私有属性/实例属性的区别在我的另一篇文章中有具体描述js–属性和方法(私有/公有)
function doSum(x,y){
doSum.totalSum=doSum+x+y;
return(doSum.totalSum);
}
  • 对参数进行健壮形参处理是有必要的。如下:
function addTwo(x,y){
if (arguments.length!=2)
throw "addTwo requires 2 arguments"
if ((typeof (x) !="number")||(typeof (y) !="number"))
throw "addTwo parameter type mismatch"
alert(x+y);
}
  • 当调用了一个静态方法时,使用.bind函数来指定该函数执行时的this对象。
  • 与bind相似可以使用.call函数来指定this对象。
  • 有时候使用递归函数会有很优美的效果,但它可以被迭代loop来改写。 - 在将函数赋给一个变量时,一旦在函数标识符后添加了括号和参数,那么这个函数将会被执行并将返回值赋给这个变量。

对象

  • JS中对象分为四种
  • 用户定义对象,就是程序员自己写的对象。
  • 浏览器宿主对象,是浏览器支持的对象如window和navigator。
  • DOM文档对象模型,如document都是window对象的属性。
  • JS原生对象,如String和Object等。
  • 宿主环境的不同是目前JavaScript面临的主要困难,因此一些流行框架jQuery/Dojo/YUI/Prototype提供了帮助。
  • 销毁对象:myObj=null;
  • 移除实例属性:delete myObj.name
  • 检查实例的属性是否存在:hasOwnProperty();
  • 可以使用数组的语法去访问属性:myString["spaced example"];
  • 枚举for in;
for(var prop in obj){
if(obj hasOwnProperty(prop)){
alert(obj[prop]);
}
}


  • 由于对象和数组是引用类型,将其赋值给多个变量时,他们实际指向的是一个对象空间,修改是共享的。如果需要的话,应该用new建立新的对象。
  • 两个对象用==符号===符号进行比较是,只有当两个对象变量都指向同一个实例时,才true
  • 对象的一些属性或方法,见表6-2 P185。
  • Object是所有对象的超类,继承Object的所有方法和属性。
  • 对象实例是通过构造函数(constructor)创建的。每个构造函数都包含一个对象原型。
  • 对象类型与对象实例的关系:Array和String是Object的不同类,而包含一个String引用的变量是对象的一个实例,这个实例可以有多个引用。而构造函数就是去产生一个类的原型。
  • 构造函数和原型组合模式

在实际开发中,我们可以使用构造函数来定义对象的属性,使用原型来定义共享的属性和方法,这样我们就可以传递不同的参数来创建出不同的对象,同时又拥有了共享的方法和属性。
function Gf(name,bar){  
this.name = name;
this.bar = bar;
}
Gf.prototype = {
constructor : Gf,
sayWhat : function() {
alert(this.name + "said:love you forever");
}
}
var gf1 = new Gf("vivian", "f");
var gf2 = new Gf("vivian1", "c");

在这个例子中,我们再构造函数中定义了对象各自的属性值,在原型对象中定义了constructor属性和sayWhat函数,这样gf1和gf2属性之间就不会产生影响了。这种模式也是实际开发中最常用的对象定义方式,包括很多js库(bootstrap等)默认的采用的模式。

  • 静态属性又称为类属性。
  • 差异继承法,可以用于生成一个继承于某父原型的原型。这种方法可以通过迭代形成一个原型链。
UltraRobot.prototype=new Robot();
  • prototype.constructor属性的可变性:因为每实例化一个对象(new),就会同时为其创建一个prototype对象,这个对象也会自动获取一个新的constructor属性,同样的,如果覆盖了一个prototype,那么这个prototype.constructor也会随着引用而变化。
  • .created(fun)函数是一种新型的工厂模式,他会生成一个以fun对象为原型的新的实例。fun中所有的属性和方法都会被当成可共享。此时新函数的constructor属性指向fun对象。
  • ECMAScript5的3个对象新特性
  • Object.defineProperties()用来控制属性的特性。特性包含:
Object.defineProperty(a,"foo",{
value:"Hello",//值
enumerable:true,//for-in可见
configurable:false,//属性的属性可修改
writeable:false//属性的值可修改
});
  • Object.getOwnPropertyDescriptior(a,”foo”)返回a对象的foo属性的属性对象。
  • Object.isExtensible(a)返回a对象是否还能添加更多的属性或方法。
  • Object.preventExtensions(a)使得的可拓展性设置为false。
  • Object.isSealed(a)返回当前对象的密封性
  • Object.seal(a).设置a所有属性的configurable都设置成false并使其不可拓展。如果writable属性为真那么属性的值可以修改,writable属性可修改。
  • Object.isFrozen(a)返回当前对象的冰冻性
  • Object.freeze(a)在seal的基础上设置所有属性值不可修改。