《JavaScript面向对象编程指南》 学习笔记
《JavaScript面向对象编程指南》 学习笔记
JavaScript面向对象编程指南 PDF书签版
第一章、引言
1.5 面向对象的程序设计常用概念
对象(名词):是指“事物”在程序设计语言中的表现形式。
这里的事物可以是任何东西,我们可以看到它们具有某些明确特征,能执行某些动作。
这些对象特征就叫做属性(形容词),动作称之为方法(动词)。
类:实际上就是对象的设计蓝图或制作配方。类更多的是一种模板,而对象就是在这些模版的基础上被创建出来的。
封装:主要阐述对象中包含的内容。通常包括:
- 相关数据(用于存储属性)
- 基于这些数据所能做的事(所能调用的方法)
聚合:将几个现有对象合并成一个新对象的过程
继承:实现代码重用
多态:不同对象通过相同的方法调用来实现各自行为的能力
第二章、基本数据类型、数组、循环及条件表达式
2.3.2 指数表示法
2e+3表示在数字2后面加3个0,即2000
typeof Infinity // number
typeof NaN // number
typeof null // object null值表示一个空指针对象
2.3.4 惰性求值
Javascript引擎在一个逻辑表达式中遇到一个非布尔类型操作数,
那么该操作数的值就会成为该表达式返回的结果。
true || "something" //true
true && "something" //"something"
2.9 练习题
var s = "1s"; //隐式转换Number()用于任何数据类型
s++ //NaN
10 % "0" //NaN 如果被除数是有限大的数值而除数是零,则结果是NaN
//乘法口诀程序代码
for(var i=1;i<10;i++){
for(var j=1;j<=i;j++){
document.write(j+"*"+i+"="+i*j+" ");
}
document.write("<br>");
}
第三章、函数
3.1.2 函数参数
函数内部都有一个内建的arguments数组,能返回函数所接收的所有参数
functionsumOnSteroids(){
var i,res = 0;
for(i = 0; i < arguments.length; i++){
res += arguments[i];
}
return res;
}
sumOnSteroids(1,2,3,4,5,6); //21
3.3 函数的作用域
var a = 123;
functionf(){
alert(a); //undefined 这是因为函数域优先于全局域
var a = 1;
alert(a); //1
}
f();
3.4.2 回调函数
当我们将函数B传递给函数A,并由A来执行B时,B就成了一个回调函数
functionA(a,b,c,callback){
var i=0,ar = [];
for(i=0;i<3;i++){
ar[i] = callback(arguments[i]*2);
}
return ar;
}
functionB(a){ //回调函数
return a+1;
}
A(a,b,c,B)
3.4.4 自调函数
(function(name){
alert('Hello '+name+' !');
})('Jesse') //Hello Jesse !
//第二对括号起到的是立即调用的作用,同时也是向函数传递参数的地方
使用自调函数的好处是不会产生任何全局变量,缺点是无法重复执行,这使得匿名自调函数最合适于执行一些一次性的或者初始化的任务
3.4.5 私有函数
functiona(param){
functionb(theinput){ //私有函数
return theinput * 2
};
return 'The result is '+b(param)
}
使用私有函数的好处:
- 有助于全局命名空间的纯净性(命名冲突的机会很小)
- 私有性--不被外部其他用用程序所用
3.4.7 能重写自己的函数
这对于要执行某些一次性初始化工作的函数非常有用
functiona(){
alert('A'); //第一次调用该函数时该语句会被执行
a = function(){ //第一次调用时a被赋予新函数
alert('B'); //第二次调用该函数时该语句会被执行
};
}
var a = function(){
functionsomeSetup(){
var setup = 'done'
}
functionactualWork(){
alert('work')
}
someSetup();
return actualWork;
}();
3.5 闭包
3.5.1 作用域链
在函数内定义的变量在函数外是不可见的,
但是如果该变量是在某个代码块中定义的(if或for语句中),它在代码块外是可见的。
3.5.2 词法作用域
在javascript中每个函数都有一个属于自己的词法作用域,也就是说每个函数
在被定义时(而非执行时)都会创建一个属于自己的环境(即作用域)
functionf1(){var a = 1;f2();}
functionf2(){return a;} //f2()被定义时a是不可见的,只能访问自身作用域和全局作用域
f1(); //a is not defined
3.5.3 利用闭包突破作用域链
3.5.3.1 闭包#1
functionf(){
var b = "m";
return function(){ //有着私有作用域,可以访问f()的作用域和全局作用域
return b;
}
}
var n = f();
n(); //m
f()是全局函数,我们可以将它的返回值赋值给另一个全局变量,
从而生成一个可以访问f()私有空间的新全局函数
3.5.3.3 相关定义与闭包#3
如果一个函数在其父函数返回之后想留住对父级作用域的链接,就必须要为此建立一个闭包
3.5.3.4 循环中的闭包
functionf(){
var a = [];
for(var i = 0; i < 3; i++){
a[i] = function(){
return i;
}
}
return a;
}
var s = f();
s[0](); //3
s[1](); //3
s[2](); //3
我们在这里创建了3个闭包,它们都指向一个共同的局部变量i,
但是闭包不会记录它们的值,他们所拥有的只是一个i的引用,
因此只能返回i的当前值(循环结束时i=3).
functionf(){
var a = [];
for(var i = 0; i < 3; i++){
a[i] = (function(x){
return function(){
return x;
}
})(i);
}
return a;
}
var s = f();
s[0](); //0
s[1](); //1
s[2](); //2
3.7 练习题
1.十六进制值转为颜色函数getRGB()
functiongetRGB(hex){
var rgb=[0,0,0];
if(/#(..)(..)(..)/g.test(hex)){
rgb=[parseInt(RegExp.$1,16),parseInt(RegExp.$2,16),parseInt(RegExp.$3,16)];
};
return "rgb("+rgb.join(",")+")";
}
getRGB('#00ff00'); //"rgb(0,255,0)"
第四章、对象
4.1 从数组到对象
用[]定义数组的方法我们称之为数组文本标识法
用{}定义对象的方法我们称之为对象文本标识法
4.1.2 哈希表、关联型数组
在javascript中我们用数组表示索引型数组,用对象表示关联型数组
4.1.3 访问对象属性
一般通过以下两种方式访问对象的属性:
- 中括号表示法:hero['name']
- 点号表示法:hero.name
4.1.7 构造器函数
functionHero(name){ //构造器函数首字母大写
this.name = name;
this.occupation = 'ninja'
}
var hero = new Hero('jesse'); //使用new操作符创建新对象
hero.name; //ninja
使用构造器函数的好处是能利用同一个构造器函数通过传参从而创建出不同的对象。
4.1.8 全局对象
事实上程序所在的宿主环境一般都会为其提供一个全局对象,
而所谓的全局变量其实只不过是该对象的属性
4.1.9 构造器属性
构造器属性实际上是一个指向用于创建该对象的构造器函数的引用
hero.contructor //Hero
通过instanceof操作符,我们可以测试一个对象是不是由某个指定的构造器函数所创建的
hero instanceof Hero; //true
4.1.12 传递对象
引用类型,因为其值大小不固定,因此栈内存中存放的只是该对象的访问地址,(即该对象的引用)
堆内存为这个值分配空间。因此我们在引用上所做的任何改动,都会影响到他所引用的源对象。
4.2 内建对象
4.2.1 Object
所有对象都继承自Object对象,因此都具有toLocaleString()、toString()和valueOf()方法。
var o = new Object();
var o = {};
alert(o); //[object,Object]
由于alert()要接收字符串参数,所以它会在后台调用toString()方法
Object构造器的成员:
用Object()构造器所建对象的成员:
4.2.2 Array
var a = new Array();
var a = [];
typeof a; //'object' 数组也是对象
值得关注的数组的属性与方法
- length属性:定义数组时会自动生成length属性,而一般对象中没有
- sort()、join()、slice()、splice()
Array对象的成员:
4.2.3 Function
函数实际上也是一种对象,函数对象的内建构造器是Function()
定义函数的三种方式:
function sum(a,b){return a + b;}; //函数声明
var sum = function(a,b){return a + b;}; //函数表达式
var sum = new Function('a','b','return a + b;'); //Function构造器 避免使用
4.2.3.1 Function对象的属性:
- prototype属性详见第五章
- length:用于记录该函数所拥有的参数数量
-
caller:返回一个调用该函数对象的外层函数引用
functionA(){return A.caller;} functionB(){return A();} B(); //function B(){return A();}
4.2.3.2 Function对象的方法
Function对象继承自Object对象,默认拥有Object对象的所有方法
call()、apply()方法都能让对象去借用其他对象中的方法为己所用,这也是一种代码重用的方式。
-
call()方法:
var someObj = { name: 'Ninja', say: function(who){ return 'Hello '+who+', my name is '+ this.name; } }; var myObj = { name:'Jesse' }; someObj.say.call(myObj, 'Dude');//"Hello Dude, my name is Jesse" //当say()被调用时其中的this就被自动设置成myObj对象的引用
如果我们调用call方法时需要传递更多的参数,可以在后面依次加入他们
someObj.say.call(myObj,'a','b','c')
如果我们没有将对象传递给call()的首参数,或者传递的是null,则它的调用对象默认为全局对象
- apply()方法:
apply()的工作方式与call()基本相同,唯一的不同之处在于第二个参数的传递形式apply()方法的第二个参数是通过一个数组来传递的
someObj.say.apply(myObj,['a','b','c'])
4.2.3.3 重新认识arguments对象
- 在函数中通过arguments访问传递给函数的所有参数
- arguments对象的callee属性,该属性返回的是当前被调用的函数对象
-
通过arguments.callee属性实现匿名函数的递归调用
(function(count){ if(count < 5){ console.log(count); arguments.callee(++count); } })(1) //1,2,3,4
Function对象的成员
4.2.4 Boolean
var b = new Boolean();
typeof b; //'object'
typeof b.valueOf();// 'boolean'
4.2.5 Number
Number对象的toString()方法有一个可选的radix参数(默认10)
var n =new Number(255);
n.toString(16); // 'ff'
Number()构造器的成员
Number对象的成员
4.2.6 String
当我们将一个基本字符串当做对象来使用时,后台会执行相应的String对象创建操作
String()构造器的成员
String对象的成员
更多详情见请继续阅读下一页的精彩内容:
|
评论暂时关闭