JavaScript 語法筆記
目錄
1.JS放在哪
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!-- 瀏覽器不支援或禁用javascript時該元素顯示-->
<noscript>
<h1 >"請支援javascript功能"</h1>;
</noscript>
<!-- type one action when click -->
<a href="javascript:alert('hello world!')">hello world!</a>
<!-- type two -->
<script type="text/javascript">
alert("hello world!");
</script>
<!-- type three defer:推遲指令碼執行 async:啟動新執行緒,非同步執行指令碼 -->
<!-- 兩種屬性只可用於此種外部指令碼檔案模式-->
<script src="first.js" type="text/javascript" defer async></script>
</body>
</html>
2.定義變數
javascript是弱型別語言,可以不定義變數直接而使用,存在顯示定義變數(使用關鍵字var)和隱式定義變數兩種,變數的資料型別也可隨意轉變。
<script type="text/javascript">
var a = true;
b = 2;
b = false;
</script>
3.基本資料型別
3.1 5種基本資料型別
- 數值型別
<script type="text/javascript">
//科學計數法
var a = 3E2; //300
var b = 2.1e-2; //0.021
//整數部分只有0時,可省略
var c = 0.3;
var d = .3; //0.3
//非十進位制計數
var e = 0o14; //八進位制
var f = 0x10; //十六進位制
</script>
- 布林型別
true 或 false
- 字串型別
必須用引號括起來,可為單引號,也可為雙引號
- undefined型別
用於表示某個變數或屬性不存在,或已建立但未為其分匹配值
- null型別
用於表示變數有值,且為null
3.2 變數作用域
全域性變數:函式外定義的 + 函式內不用var定義的 變數
區域性變數:函式內用var定義的變數
- 區域性變數的作用域僅限於該函式,javascript變數不存在塊範圍;
- 當變數同名時,在區域性變數作用域內,區域性變數會覆蓋全域性變數
3.3 變數提升
變數提升機制,指的是變數宣告總是被直譯器“提升”到函式體的頂部。
- 只是提升區域性變數
- 只是提升宣告部分,不包括賦值部分
- 只要有宣告變數的語句都會被提升,不論該語句是否執行或有沒有機會執行
<script type="text/javascript">
var a = "全域性變數";
function f(){
alert(a); //undefined
var a = "區域性變數";
alert(a); //區域性變數
}
f();
</script>
所以以上程式碼效果等同於如下
<script type="text/javascript">
var a = "全域性變數";
function f(){
var a; //變數宣告提升
alert(a); //undefined
a = "區域性變數";
alert(a); //區域性變數
}
f();
</script>
3.4 let變數
- let 變數存在塊作用域
- let變數不會自動新增為全域性window物件的屬性
- let變數不會提前裝載
<script type="text/javascript">
var a = "全域性變數";
function f(){
// 區域性變數a覆蓋了全域性變數a,故全域性變數無效
// 由於let變數不會提前裝載,故此處的a為未定義的變數
alert(a); //語法錯誤
let a = "區域性變數";
alert(a); //區域性變數
}
f();
</script>
3.5 const定義變數
- 必須在定義時指定初始值,且以後不能改變值
4. 複合型別
javascript複合型別大致有以下三種:
- Object:物件
- Array:陣列
- Function:方法
4.1 陣列
- 陣列長度可變
- 同一個陣列的元素型別可互不相同
- 訪問陣列元素時不存在越界,訪問未賦值的陣列元素時,該元素值為undefined
// 建立陣列的三種方式
var a = new Array();
var b = [];
var c = [1,3,true];
- 陣列作為棧使用
push(e):元素入棧,返回入棧後陣列長度
pop():元素出棧,返回出棧元素
入棧還是出棧,都是在陣列的下標大的地方操作
- 陣列作為佇列使用
unshift(e):元素如佇列,返回如佇列後陣列長度
shift():元素出佇列,返回出佇列元素
入佇列還是出佇列,都是在陣列下標小(0)的地方操作
4.2 函式
for in迴圈
- 當遍歷陣列時,迴圈計數器是陣列元素的索引值
- 當遍歷物件時,迴圈計數器是物件的屬性名
4.2.1 函式的定義
- 返回值不需要資料型別宣告,形參也不需要資料型別宣告
//命名函式
function f1(param-list){
statements
}
//匿名函式
[var f2 = ] function(param-list){
statements
};
[var f3 = ] new Function('param1','param2', ... , "statements");
4.2.2 函式、類、物件、方法、變數
函式是javascript中的“一等公民”,定義一個函式後,就得到了一個與函式名相同的類,也得到了一個Function類例項物件,它通常會附加給某個物件(預設window),作為其方法,最後,它也是一個變數。
<script type="text/javascript">
var person = function(name, age){
this.name = name;
this.age = age;
this.talk = function(){
document.write("Hi,I`m "+name+"<br />");
}
var walk = function(){
document.write("I am "+age+",I can walk..."+"<br />");
}
walk();
}
// person是Function的例項物件
alert(typeof person);
//person是一個方法,附屬於window
person("Tom",18);
// person是一個類
var a = new person("Jerry",16);
a.talk();
//person是全域性變數,此處被重新賦值為字串
person = "no function";
alert(typeof person);
</script>
4.2.3 函式的例項屬性和類屬性
函式中的變數分為三種:
- 區域性變數:在函式中用var宣告的變數
- 例項屬性:在函式中以this字首修飾的變數
- 類屬性:在函式中以函式名字首修飾的變數
4.2.4 函式呼叫
1. 直接呼叫函式
呼叫者:函式附加的物件
呼叫者.函式(引數...)
2. 以call()方法呼叫
函式.call(呼叫者, 引數...)
<script type="text/javascript">
// 定義一個each函式
var each = function(array , fn)
{
for(var index in array)
{
// 以window為呼叫者來呼叫fn函式,
// index、array[index]是傳給fn函式的引數
fn.call(null, index , array[index]);
}
}
// 呼叫each函式,第一個引數是陣列,第二個引數是函式
each([4, 20 , 3] , function(index , ele)
{
alert(this);
document.write("第" + index + "個元素是:" + ele + "<br />");
});
</script>
call和apply的第一個引數是null/undefined時函式內的的this指向window或global
3.以apply()方法呼叫
函式.apply(呼叫者, [引數1, 引數2,... ])
4.2.5 函式的獨立性
雖然定義函式時,可以將函式定義為某個類、某個物件的方法(助於引用時標識該方法,個人理解),但函式是獨立的,不屬於其他的類或物件。
- 樣例一
<script type="text/javascript">
function Person(name)
{
this.name = name;
this.info = function()
{
console.log("我的name是:" + this.name);
}
}
var p = new Person("Tom");
// 呼叫p物件的info方法
p.info();
var name = "win";
// 以window物件作為呼叫者來呼叫p物件的info方法
p.info.call(window);
</script>
執行結果
函式的呼叫者,只是指明瞭函式執行的環境(this),p.info() 呼叫者是p物件,其name屬性值為Tom;p.info.call(window) 呼叫者是window,其name屬性值為win
- 樣例二
<script type="text/javascript">
// 定義Dog函式,等同於定義了Dog類
function Dog(name , age , bark)
{
// 將name、age、bark形參賦值給name、age、bark例項屬性
this.name = name;
this.age = age;
this.bark = bark;
// 使用內嵌函式為Dog例項定義方法
this.info = function()
{
return this.name + "的年紀為:" + this.age
+ ",它的叫聲:" + this.bark;
}
}
// 建立Dog的例項
var dog = new Dog("旺財" , 3 , '汪汪,汪汪...');
// 建立Cat函式,對應Cat類
function Cat(name,age)
{
this.name = name;
this.age = age;
}
// 建立Cat例項。
var cat = new Cat("kitty" , 2);
// 將dog例項的info方法分離出來,再通過call方法完呼叫info方法,
// 此時以cat為呼叫者
console.log(dog.info.call(cat));
</script>
執行結果
4.2.6 函式提升
函式提升的前提是該函式採用命名函式的形式定義函式
- 樣例一(提升)
<script type="text/javascript">
// 呼叫add函式
console.log(add(2, 5));
// 定義add函式(會發生函式提升)
function add(a , b)
{
console.log("執行add函式");
return a + b;
}
</script>
相當於
<script type="text/javascript">
// 定義add函式
function add(a , b)
{
console.log("執行add函式");
return a + b;
}
// 呼叫add函式
console.log(add(2, 5));
</script>
- 樣例二(不提升)
<script type="text/javascript">
// 呼叫add函式
console.log(add(2, 5)); //error
// 定義add函式,此時只提升add變數名,函式定義不會被提升
var add = function(a , b)
{
console.log("執行add函式");
return a + b;
}
</script>
相當於
<script type="text/javascript">
var add;
// 呼叫add函式
console.log(add(2, 5));
// 定義add函式,此時只提升add變數名,函式定義不會被提升
add = function(a , b)
{
console.log("執行add函式");
return a + b;
}
</script>
- 樣例三(提升)
<script type="text/javascript">
function test(){
// 呼叫add函式
console.log(add(2, 5));
// 定義add函式(會發生函式提升)
function add(a , b)
{
console.log("執行add函式");
return a + b;
}
}
test();
</script>
相當於
<script type="text/javascript">
function test(){
function add(a , b)
{
console.log("執行add函式");
return a + b;
}
// 呼叫add函式
console.log(add(2, 5));
}
test();
</script>
- 樣例四(不提升)
<script type="text/javascript">
function test(){
// 呼叫add函式
console.log(add(2, 5)); //error
// 定義add函式,此時只提升add變數名,函式定義不會被提升
var add = function(a , b)
{
console.log("執行add函式");
return a + b;
}
}
test();
</script>
相當於
<script type="text/javascript">
function test(){
var add;
// 呼叫add函式
console.log(add(2, 5)); //error
// 定義add函式,此時只提升add變數名,函式定義不會被提升
add = function(a , b)
{
console.log("執行add函式");
return a + b;
}
}
test();
</script>
4.2.7 變數與函式同名
定義變數時賦值,不論在同名函式前還是後,都會覆蓋同名函式;定義變數時不賦值,不論在同名函式前還是後,同名函式都會覆蓋變數
<script type="text/javascript">
function a(){
}
var a; // 定義變數,不指定初始值
console.log(a);// 輸出a的函式體
var b; // 定義變數,不指定初始值
function b(){
}
console.log(b);// 輸出b的函式體
var c = 1; // 定義變數,並指定初始值
function c(){
}
console.log(c);// 輸出1
function d(){
}
var d = 1; // 定義變數,並指定初始值
console.log(d);// 輸出1
</script>
4.2.8 箭頭函式
箭頭函式相當於Lambda表示式,形如 (param1, param2, ... ) => { statements }
- 只有一個形參時,可省略括號
- 沒有形參時,不可省略括號
- 只有一條語句時,可省略花括號
- 只有一條語句,且是return語句時,可省略return
- 箭頭函式不繫結arguments,所以箭頭函式的arguments總是引用當前上下文的arguments
<script type="text/javascript">
//var arguments = "Tom";
// 箭頭函式中arguments引用當前上下的arguments,即"Tom"字串
var arr = () => arguments;
console.log(arr()); // 輸出Tom
function foo()
{
// 箭頭函式中arguments引用當前上下的arguments,
// 此時arguments代表呼叫foo函式的引數
var f = (i) => 'Hello,' + arguments[0];
return f(2);
}
console.log(foo("Tom", "Jerry")); // 輸出Hello,Tom
</script>
對於普通函式
如果直接呼叫普通函式,函式中的this代表全域性物件(window);如果通過new呼叫函式建立物件,那麼函式中的this代表所建立的物件。
<script type="text/javascript">
var f = function(){
this.age = 100;
console.log(this + this.age);
window.age = 90;
console.log(this + this.age);
}
f(); //直接呼叫函式f,則函式f中的this代表window
new f(); //通過new建立物件使函式f得到呼叫,此時函式f中的this代表f物件
</script>
再看一個例子
<script type="text/javascript">
function Person() {
// Person()作為構造器使用時,this代表該構造器建立的物件
this.age = 0;
setInterval(function growUp(){
// 對於普通函式來說,直接執行該函式時,this代表全域性物件(window)
// 因此下面的this不同於Person構造器中的this
console.log(this === window);
this.age++;
}, 1000);
}
var p = new Person();
setInterval(function(){
console.log(p.age); // 此處訪問p物件的age,將總是輸出0
}, 1000);
</script>
此處growUp方法裡的this是始終為window,區別於以下箭頭函式時。
對於箭頭函式
箭頭函式中的this總是代表包含箭頭函式的上下文
<script type="text/javascript">
function Person() {
// Person()作為構造器使用時,this代表該構造器建立的物件
this.age = 0;
setInterval(() => {
// 箭頭函式中this總代表包含箭頭函式的上下文。
console.log(this === window);
// 此處的this,將完全等同於Person構造器中的this
this.age++;
}, 1000);
}
var p = new Person();
setInterval(function(){
console.log(p.age); // 此處訪問p物件的age,將總是輸出數值不斷加1
}, 1000);
</script>
值得注意的是,此處箭頭函式裡的this等同於Person構造器裡的this,此處Person構造器裡的this代表Person物件,故箭頭函式裡的this為Person物件
<script type="text/javascript">
function Person() {
// Person()作為構造器使用時,this代表該構造器建立的物件
this.age = 0;
setInterval(() => {
// 箭頭函式中this總代表包含箭頭函式的上下文。
console.log(this === window); //true
// 此處的this,將完全等同於Person構造器中的this
this.age++;
}, 1000);
}
Person();
setInterval(function(){
console.log(window.age); // 此處訪問window物件的age,將總是輸出數值不斷加1
}, 1000);
</script>
此時直接呼叫Person函式,導致Person函式裡的this代表window,也就是箭頭函式的上下文是window,所以箭頭函式的this就是window
5. 物件導向
javascript函式定義不支援繼承語法,沒有完善的繼承機制,因此習慣上稱Javascript是基於物件的指令碼語言。所有的類是Object類的子類外,沒有其他父子繼承關係。
5.1 prototype實現繼承
javascript的prototype屬性代表了該類的原型物件,其是一Object物件,將javascript的prototye屬性設為父類例項,可實現javascript語言的繼承。
<script type="text/javascript">
// 定義一個Person類
function Person(name, age)
{
this.name = name;
this.age = age;
}
// 使用prototype為Person類新增sayHello方法
Person.prototype.sayHello = function()
{
console.log(this.name + "向您打招呼!");
}
var per = new Person("牛魔王", 22);
per.sayHello(); // 輸出:牛魔王向您打招呼!
// 定義一個Student類
function Student(grade){
this.grade = grade;
}
// 將Student的prototype設為Person物件
Student.prototype = new Person("未命名" , 0);
// 使用prototype為Student類新增intro方法
Student.prototype.intro = function(){
console.log("%s是個學生,讀%d年級" , this.name, this.grade);
}
var stu = new Student(5);
stu.name = "孫悟空";
console.log(stu instanceof Student); // 輸出true
console.log(stu instanceof Person); // 輸出true
stu.sayHello(); // 輸出:孫悟空向您打招呼!
stu.intro(); //輸出:孫悟空是個學生,讀5年級
</script>
Student的原型是Person物件,相當於設定Student繼承了Person,這樣Student類將會得到Person類的屬性和方法。Student物件既可呼叫Person的例項方法,也可呼叫Student的例項方法。
5.2 構造器實現偽繼承
<script type="text/javascript">
// 定義一個Person類
function Person(name, age)
{
this.name = name;
this.age = age;
// 為Person類定義sayHello方法
this.sayHello = function()
{
console.log(this.name + "向您打招呼!");
}
}
var per = new Person("牛魔王", 22);
per.sayHello(); // 輸出:牛魔王向您打招呼!
// 定義Student類
function Student(name, age, grade)
{
// 定義一個例項屬性引用Person類
this.inherit_temp = Person;
// 呼叫Person類的構造器
this.inherit_temp(name, age);
this.grade = grade;
}
// 使用prototype為Student類新增intro方法
Student.prototype.intro = function(){
console.log("%s是個學生,讀%d年級" , this.name, this.grade);
}
var stu = new Student("孫悟空", 34, 5);
console.log(stu instanceof Student); // 輸出true
console.log(stu instanceof Person); // 偽繼承,所以輸出false
stu.sayHello(); // 輸出:孫悟空向您打招呼!
stu.intro(); //輸出:孫悟空是個學生,讀5年級
</script>
第21行,以this為呼叫者,呼叫了Person的構造器,這樣Person構造器中的this就是Student。Student物件既可呼叫Person的例項方法,也可呼叫Student的例項方法。
5.3 使用apply或call實現偽繼承
這種方式和5.2相似
<script type="text/javascript">
// 定義一個Person類
function Person(name, age)
{
this.name = name;
this.age = age;
// 為Person類定義sayHello方法
this.sayHello = function()
{
console.log(this.name + "向您打招呼!");
}
}
var per = new Person("牛魔王", 22);
per.sayHello(); // 輸出:牛魔王向您打招呼!
// 定義Student類
function Student(name, age, grade)
{
Person.call(this, name, age);
// Person.apply(this, [name, age]);
this.grade = grade;
}
// 使用prototype為Student類新增intro方法
Student.prototype.intro = function(){
console.log("%s是個學生,讀%d年級" , this.name, this.grade);
}
var stu = new Student("孫悟空", 34, 5);
console.log(stu instanceof Student); // 輸出true
console.log(stu instanceof Person); // 偽繼承,所以輸出false
stu.sayHello(); // 輸出:孫悟空向您打招呼!
stu.intro(); //輸出:孫悟空是個學生,讀5年級
</script>
6. 建立物件
- 使用new關鍵字呼叫構造器建立物件
var p = new Person();
- 使用Object類建立物件
var obj = new Object();
- 使用JSON語法建立物件
var person = {
name:"Tom",
age:20
}
相關文章
- Markdown語法筆記筆記
- c++語法筆記C++筆記
- JavaScript學習筆記2: js書寫語法及變數JavaScript筆記JS變數
- JavaScript 藝術之美(一)序言和 JavaScript 語法(卞懂的學習筆記)JavaScript筆記
- swift語法-讀書筆記Swift筆記
- Java基礎 語法筆記Java筆記
- Java基礎語法筆記Java筆記
- 【開發筆記】swift語法小記筆記Swift
- JavaScript語法JavaScript
- Python學習筆記(語法篇)Python筆記
- Python筆記_1語法總結Python筆記
- 《JavaScript語言精粹》學習筆記一JavaScript筆記
- 《JavaScript語言精粹》學習筆記二JavaScript筆記
- javascript基本語法JavaScript
- swift學習筆記《2》-swift語法Swift筆記
- 《PHP學習筆記——PHP基本語法》PHP筆記
- 自學PHP筆記(一)PHP語法PHP筆記
- Scala學習筆記(2)-基礎語法筆記
- 《Haskell趣學指南》筆記之基本語法Haskell筆記
- 自學PHP筆記(一)PHP基本語法PHP筆記
- 04JavaScript語法JavaScript
- JSX(JavaScript XML)語法JSJavaScriptXML
- JavaScript 語法介紹JavaScript
- JavaScript 基礎語法JavaScript
- Javascript中的with語法JavaScript
- JavaScript 函式語法JavaScript函式
- JavaScript的核心語法JavaScript
- JavaScript 新語法 「雙問號語法」與「可選鏈語法」JavaScript
- Python 3 學習筆記之——基礎語法Python筆記
- 入門筆記 --- Golang 語法注意事項(一)筆記Golang
- docker 筆記3 dockerfile語法及最佳實踐Docker筆記
- ES6語法學習筆記之promise筆記Promise
- Go 學習筆記 - Go 基礎語法(2)Go筆記
- Go學習筆記 - Go 基礎語法(1)Go筆記
- Javascript與抽象語法樹JavaScript抽象語法樹
- PHP Javascript 語法對照PHPJavaScript
- ES6語法學習筆記之物件簡潔語法,及新增內容筆記物件
- 【show me the code】Python練習題&語法筆記 2Python筆記