JS學習小結(jié):
學習javaScript腳本語言,首先我們要知道Javascript是什么?
Javascript是什么,簡稱Js,Js是一種基于對象(Object)和事件驅(qū)動(Event Driven)并具有安全性能的腳本語言,使用它的目的是與HTML超文本標記語言、Java 腳本語言(Java小程序)一起實現(xiàn)在一個Web頁面中鏈接多個對象,與Web客戶交互作用。從而可以開發(fā)客戶端的應用程序等。
當前什么越來越強調(diào)溝通,而Js是最接近前后端的語言,越來越多的前后端框架的支持,使他的前途很明朗,作為一種解釋型語言,Js強調(diào)實時,在線。
先看下Js的特性:腳本編寫語言,基于對象的語言,簡單性,安全性,動態(tài)性和跨平臺特性。
Js的命名規(guī)范:有兩種常用的命名規(guī)則
匈牙利命名法的原則:變量名=屬性+類型+對象描述。他的關(guān)鍵是:以一個或多個小寫字母作為前綴,前綴之后是一個或多個首字母大寫的單詞組合,該單詞指明變量的用途。
駝峰命名法的原則:第一個單詞以小寫字母開始,之后每一個單詞的首字母大寫。例如:myFirstName、myLastName,這樣的變量名看上去就像駝峰一樣此起彼伏,因此得名。駝峰法的關(guān)鍵是:除第一個單詞外,其他單詞首字母大小,混合使用大小寫字母來構(gòu)成變量名和函數(shù)名,還可以使用下劃線來形成邏輯斷點,這樣更能增強代碼的可讀性。
JS的注釋規(guī)范:
JS中單行注釋用“ // 注釋內(nèi)容” 標識,多行注釋使用“ /* 注釋內(nèi)容 */ “標識。注釋的作用是提高代碼的可讀性,不僅自己以后用著方便,也有助于別人閱讀和理解你所編寫的JS代碼,注釋中的內(nèi)容不會在網(wǎng)頁中顯示。為了方便閱讀,注釋一般放在需要解釋的語句結(jié)尾處或者周圍。
在JavaScript中四種基本的數(shù)據(jù)類型:數(shù)值(整數(shù)和實數(shù))、字符串型(用“”號或‘’括起來的字符或數(shù)值)、布爾型(使True或False表示)和空值。在JavaScript的基本類型中的數(shù)據(jù)可以是常量,也可以變量。由于JavaScript采用弱類型的形式,因而一個數(shù)據(jù)的變量或常量不必首先作聲明,而是在使用或賦值時確定其數(shù)據(jù)的類型的。當然也可以先聲明該數(shù)據(jù)的類型,它是通過在賦值時自動說明其數(shù)據(jù)類型的。
一個為 undefined 的值就是指在變量被創(chuàng)建后,但未給該變量賦值以前所具有的值。
--------------------------------------------------------------------------------------------------------------------
下面是一下常用語法:
1.對象定義方式
空對象:沒有任何屬性和方法
var obj = {};
定義對象的屬性:
obj.xx = "123";
定義對象的方法:
obj.function = function(){};
--------------------------------------------------------------------------------------------------------------------
2.函數(shù)的定義方式:
JavaScript函數(shù)定義Function 函數(shù)名 (參數(shù),變元){函數(shù)體;.Return 表達式;}說明: 當調(diào)用函數(shù)時,所用變量或字面量均可作為變元傳遞。 函數(shù)由關(guān)鍵字Function定義。 函數(shù)名:定義自己函數(shù)的名字。 參數(shù)表,是傳遞給函數(shù)使用或操作的值,其值可以是常量 ,變量或其它表達式。 通過指定函數(shù)名(實參)來調(diào)用一個函數(shù)。 必須使用Return將值返回。 函數(shù)名對大小寫是敏感的。
函數(shù)中的形式參數(shù): 在函數(shù)的定義中,我們看到函數(shù)名后有參數(shù)表,這些參數(shù)變量可能是一個或幾個。那么怎樣才能確定參數(shù)變量的個數(shù)呢?在JavaScript中可通過arguments .Length來檢查參數(shù)的個數(shù)。例:Function function_Name(exp1,exp2,exp3,exp4)Number =function _Name . arguments .length;if (Number>1)document.wrile(exp2);if (Number>2)document.write(exp3);if(Number>3)document.write(exp4);...
--------------------------------------------------------------------------------------------------------------------
3 對象的引用傳遞
var person={name:'anker',age:100};
var x = person;
x.age = 19;
console.log(x.age);//19
console.log(person.age);//19
說明js中對象的賦值也是采用引用的方式,同時指向同一個對象。
function changebj(obj) {obj.age = 10};
changebj(person);
console.log(person.age);
10//打印結(jié)果也是10,說明函數(shù)傳遞的也是對象的引用。修改的是同一個對象。
person.sex = '男';//若該屬性不存在則添加,若存在則覆蓋。
訪問對象的方式:
obj.name
obj["name"]或者obj['name']//必須采用雙引號或者單引號括起來
--------------------------------------------------------------------------------------------------------------------
4.匿名函數(shù)
(function(){//代碼 })(); //可立即執(zhí)行的匿名函數(shù)
解釋:,包圍函數(shù)(function(){})的第一對括號向腳本返回未命名的函數(shù),隨后一對空括號立即執(zhí)行返回的未命名函數(shù),括號內(nèi)為匿名函數(shù)的參數(shù)。
例子:(function(arg){ alert(arg+100); })(20);
這個例子返回120。
匿名函數(shù),就是沒有引用直接加上()進行執(zhí)行的函數(shù)。
var addFunc = function(a,b){
cosole.log(a+b);
};
--調(diào)用方式
addFunc(1,2);
--匿名函數(shù)
(function(a,b){console.log(a+b)})(1,2);
上面兩個函數(shù)的產(chǎn)生的結(jié)果是一樣的.只不過addFunc為函數(shù)對象的引用,而匿名函數(shù)不存在引用.
--來看個復雜的利用匿名函數(shù)的例子
var add = (function(){
var sum = 0 ;
return function(){
for(var i=0;l=arguments.length,i<l;i++){
sum+=arguments[i];
}
return sum;
};
})(); --加上括號為匿名函數(shù)的寫法,可以理解為直接執(zhí)行了此函數(shù),函數(shù)的執(zhí)行結(jié)果返回
add(1,2,3,4);
add(2);
--等價于
var func1 = function(){
var sum = 0 ;
return function(){
for(var i=0;l=arguments.length,i<l;i++){
sum+=arguments[i];
}
return sum;
};
};
var add = func1();
add(1,2,3,4);
add(2);
//現(xiàn)在有一個場景,需要設(shè)計一個函數(shù),前面每次調(diào)用,不會真正去計算,而是把參數(shù)保存下來,等到需要計算的再一起計算
var currying = function(fn){
var args = [] ;
return function(){
if(arguments.length === 0){
return fn.apply(this,args);
}else {
Array.PRototype.push.apply(args,arguments);
return arguments.callee;
}
};
}
var add = (function(){
var sum = 0 ;
return function(){
for(var i=0;l=arguments.length,i<l;i++){
sum+=arguments[i];
}
return sum;
};
})();
var add = currying(add);
add(1);
add(2);
add(3);
add();
---------------------------------------------------------------------------------------------------------------------
5.閉包
可以理解成一個函數(shù)內(nèi)的內(nèi)部函數(shù),它被創(chuàng)建在一個函數(shù)內(nèi)部,引用這其外部函數(shù)的變量值。
var a = function(){
var x = 1;
return function(y){
console.log(x+=y);//外部函數(shù)的x值就被包裹在引用對象中
}
}
var b = a();//實際上是返回function(y){...}的引用
b();//執(zhí)行上面的引用,此時的x值變成了private的屬性
閉包的兩個作用:
1.可以讀取函數(shù)體所在外部函數(shù)的局部變量
2.就是讓這些變量的值始終保持在內(nèi)存中
------------------------------------------------------------------------------------------------------------------------
6.constructor
constructor 屬性返回對創(chuàng)建此對象的數(shù)組函數(shù)的引用。
var test=new Array();
if (test.constructor==Array)//判斷test的構(gòu)造函數(shù)是否是Array
{
document.write("This is an Array");
}
var createPerson = function(name,sex,age){
this.name = name;
this.sex = sex;
this.age = age;
};
//undefined
var p1 = new createPerson('z1',19,'男');
//undefined
p1.constructor
//輸出
function (name,sex,age){
this.name = name;
this.sex = sex;
this.age = age;
}
p1.constructor == createPerson
//輸出:true
createPerson.constructor
//Function() { [native code] } //createPerson構(gòu)造函數(shù)為Function,從一個側(cè)面說明function也是對象
------------------------------------------------------------------------------------------------------------------------
7.js ==與 ===的區(qū)別
一個等號是賦值操作,==先轉(zhuǎn)換類型再比較,進行值的對比。
而===先判斷類型,如果不是同一類型直接為false,只有類型和值全部都相等,才相等。
------------------------------------------------------------------------------------------------------------------------
8.JS中一切皆對象
JS中基本數(shù)據(jù)類型,也存在著對象封裝,比如下面數(shù)字123的構(gòu)造函數(shù)是Number,test的構(gòu)造函數(shù)是String,包含length的屬性
(123).constructor
//輸出:function Number() { [native code] }
'test'.constructor
//輸出:String() { [native code] }
'test'.length;
//輸出:4
//擴展Number的函數(shù)
Number.prototype.toString = function(){
alert('hi,I/'m a number ');
};
(123).toString();
//輸出:hi,I/'m a number
Number.prototype
Number {toString: null, [[PrimitiveValue]]: 0}
------------------------------------------------------------------------------------------------------------------------
9.prototype原型
每個對象都連接到一個原型對象,并且可以從中繼承屬性。所有通過{}或者構(gòu)造函數(shù)創(chuàng)建的對象都連接到Object{}
對象通過(對象名稱.__proto__)可以查看原型
或者通過(對象名稱.constructor.prototype)查看原型
var createPerson = function(name,sex,age){
this.name = name;
this.sex = sex;
this.age = age;
};
var p1 = new createPerson('z1',19,'男');
p1.constructor
//輸出:
fucntion(name,sex,age){
this.name = name;
this.sex = sex;
this.age = age;
}
p1.constructor.prototype
//輸出:
Object {}
createPerson.prototype
//輸出:
Object {}
p1.constructor.prototype === createPerson.prototype
true
var p2 = {sex:'男'};
p2.constructor.prototype
//輸出:Object {}
/*
在javascript中,創(chuàng)建一個新對象時,可以選擇某個對象作為它的原型,比如
*/
var person = {name:'z3',age:18,sex:'男'};
Object.create = function(o){
var F = function(){};
F.prototype = o ;
return new F();
};
var anotherPerson = Object.create(person);
anotherPerson.name;//z3
//對原型對象進行更新,發(fā)現(xiàn)已創(chuàng)建的對象值也隨著變化
person.name = 'z4';
"z4"
anotherPerson.name
//輸出:"z4"
//但當對象增加相同的屬性后,原型對象的屬性變化,不影響對象的屬性值。因為對象讀取值首先讀取本身對象的值,后讀取原型的值
anotherPerson.name = 'z5';
person.name = 'z6';
//輸出:"z6"
anotherPerson.name
//輸出:"z5"
delete anotherPerson.name
//輸出:true
anotherPerson.name//輸出對象本身的屬性值,原型對象的屬性值不會被刪除,除非通過delete 原型對象.屬性輸出.
//輸出:"z6"
delete person.name
//輸出:true
anotherPerson.name
//輸出:undefined
//原型連接什么時候起作用呢?只有在檢索值的時候才被用到
//如果嘗試者去獲取對象的某個屬性值,但該對象沒有此屬性名,那么JAVASCRIPT會嘗試著從原型對象中獲取屬性值。
//如果原型對象也沒有該屬性值則再從它的原型找,直到該過程最后達到終點Object.prototype。Object
//如果想要的屬性完全不存在于原型鏈中,那么結(jié)果就是undefined。
person.age = 18;
anotherPerson.age//顯示什么?
//原型關(guān)系是一種動態(tài)的關(guān)系。如果添加一個新的屬性到原型中,該屬性會立即對所有基于該原型創(chuàng)建的對象可見。
anotherPerson.__proto__===person;//true
__proto__顯示對象的原型鏈
//可以使用hasOwnProperty方法來判斷對像是否含有某個屬性,如果對象擁有獨有的屬性,則返回true
//這個方法不會去檢查原型鏈
------------------------------------------------------------------------------------------------------------------
10. arguments
arguments 對象是函數(shù)內(nèi)部的本地變量;arguments 已經(jīng)不再是函數(shù)的屬性了。
你可以在函數(shù)內(nèi)部通過使用 arguments 對象來獲取函數(shù)的所有參數(shù)。這個對象為傳遞給函數(shù)的每個參數(shù)建立一個條目,
條目的索引號從 0 開始。例如,如果一個函數(shù)有三個參數(shù),你可以通過以下方式獲取參數(shù):
arguments[0]
arguments[1]
arguments[2]
參數(shù)也可以被重新賦值:
arguments[1] = 'new value';
arguments 對象并不是一個真正的Array。它類似于數(shù)組,但沒有數(shù)組所特有的屬性和方法,除了 length。
例如,它沒有 pop 方法。不過可以將其轉(zhuǎn)換成數(shù)組
------------------------------------------------------------------------------------------------------------------------
11.利用JS特性實現(xiàn)AOP
AOP就是面向切面編程,主要作用是把一些核心業(yè)務(wù)邏輯模塊無關(guān)的功能抽離出來,這些跟業(yè)務(wù)邏輯無關(guān)的功能
通常包括日志統(tǒng)計,安全控制,異常處理等。把這些功能抽離出來后,又通過動態(tài)織入的方式滲入到業(yè)務(wù)邏輯模塊中
在JAVA中,可以通過反射和動態(tài)代理機制來實現(xiàn)AOP。但對于javascript這種動態(tài)語言,AOP的實現(xiàn)更加簡單
在javascript中實現(xiàn)AOP,都是指把一個函數(shù)動態(tài)織入到另外一個函數(shù)中。我們可以通過擴展Function.prototype來做到這一點
*/
Function.prototype.before = function(beforefn){
var that = this ;
return function(){
beforefn.apply(this,arguments);
return that.apply(this,arguments);
};
};
Function.prototype.after = function(afterfn){
var that = this ;
return function(){
var ret =that.apply(this,arguments);
afterfn.apply(this,arguments);
return ret ;
};
};
var func = function(){
console.log(2);
};
func = func.before(function(){
console.log(1);
}).after(function(){
console.log(3);
});
func();
var func1 = document.getElementById;
undefined
func1('nt-contents');
//報錯信息如下, 是由于document.getElementById函數(shù)中的this指向為windows對象,而windows對象不存在這些變量。
VM245:1 Uncaught TypeError: Illegal invocation(…)
//寫那么復雜主要是將this的指向還是定位到document上面
var getElementById1 = (function(func){
return function(){
return func.apply(document,arguments);
}
})(document.getElementById);
------------------------------------------------------------------------------------------------------------------------
12.利用JS特性實現(xiàn)一些有趣的Function
var getId = document.getElementById1; //返回 這個對象 function(){return func.apply(document,arguments);}
var div = getId('ntp-contents');//返回func.apply(document,arguments)的對象,arguments參數(shù)值div1,func執(zhí)行閉包中的document.getElementById函數(shù)
alert(div.id);
//我們上節(jié)課講到,怎么在一個內(nèi)部函數(shù)中保持外層的this上下使用了一個變量that來保存外,還可以使用以下方法
Function.prototype.bind =function(context){
var self = this ;
return function(){
alert(self);
alert(context);
return self.apply(context,arguments);
}
};
var obj ={name : 'steven'};
var func = (function(){
alert(this.name)
}).bind(obj);
var isType =function(type){
return function(obj){
return Object.prototype.toString.call(obj)==='[object '+type+']';
};
};
var isString = isType('String');
isString('hello world');
var isArray = isType('Array');
isArray([2,3]);
13.call、apply的使用
語法
function.call(thisObj,param1,param2,param3...);
function.apply(thisObj,[param1,param2,param3...]);
用法是改變function的作用域,將參數(shù)的上下文作用域修改成thisObj對象, 也可以說this對象為thisObj.
默認的function的作用域是window,this相當于window.function
新聞熱點
疑難解答
圖片精選