今天先從一個小案例說起,面向對象的內容已經過去一半,剩下的內容也至關重要 ! 希望幫到你的朋友, 能持續(xù)關注更新 !
需求 : 圖書管理操作
- 示例代碼 :
var list = [
{name:"專業(yè)主義",author:"大前研一"},
{name:"紅樓夢",author:"曹公子"},
{name:"什么是批判",author:"阜纾柯"},
{name:"十萬個為什么钩乍?",author:"作者不詳"}
];
//01 提供構造函數(shù)
function BookListManager(){
this.bookList = null;
}
//02 設置原型對象
BookListManager.prototype = {
init:function(arrayList){
this.bookList = arrayList || [];
},
getBookByName:function (name) {
//01 能夠找到該對象,返回
for (var i = 0; i < this.bookList.length; i++)
{
var obj = this.bookList[i];
if (obj.name == name)
{
return obj;
}
}
//02 找不到這個對象谬盐,返回null
return null;
},
addBook:function (bookObj){
this.bookList.push(bookObj);
},
updateBook:function (name,author){
var book = this.getBookByName(name); //在原型方法中要調用其它的原型方法需要使用this
book.author = author;
},
removeBook:function (name){
var book = this.getBookByName(name);
var index = this.bookList.indexOf(book); //返回指定對象的索引氯材,如果沒有那么就返回-1
if(index == -1)
{
throw "要刪除的數(shù)據不存在渣锦!";
}
//刪除對象
this.bookList.splice(index,1);
}
}
//03 創(chuàng)建對象
var p1 = new BookListManager();
var p2 = new BookListManager();
console.log(p1);
console.log(p2);
p1.init([{name:"城堡",author:"卡夫卡"}]);
p2.init([{name:"一分鐘學會H5開發(fā)",author:"烏拉烏拉"}]);
console.log(p1);
console.log(p2);
</script>
- 總結 : 這個小Demo就是面向對象編程的示例,自習看代碼的話會不會覺得封裝性很好,以后可以直接拿到項目中應用,而且不用擔心和別的同事的代碼發(fā)生沖突.這就是面向對象編程的好處,代碼看起來逼格也很高
嚴格模式
說明
- 在js開發(fā)中可以選擇嚴格模式或者是非嚴格模式來進行開發(fā),默認是非嚴格模式的
- 區(qū)別:在嚴格模式下氢哮,會做更嚴格的檢查袋毙,一以前在非嚴格模式下不會報錯或者是可以使用的一些語句在嚴格模式下使用會報錯或者是拋出異常。
- 嚴格模式它本身做了向后兼容:如果是支持嚴格模式的引擎冗尤,在檢測到這個字符串的時候娄猫,就會在作用域中開啟嚴格模式,如果是不支持嚴格模式的引擎生闲,那么就直接忽略處理
- 建議:推薦以后全部使用嚴格模式。
- 語法 :
"use strict"
在提供字符串設置嚴格模式的時候月幌,必須要把字符串寫在當前作用域的最頂端
**
"use strict"
注意點 :
1.在書寫字符串的使用雙引號和單引號都可以
2.字符串后面的分號可以省略
3.所有的字符必須全部小寫
4.這個字符串只能擁有10個字符**
使用注意點
- 所有的變量都必須要使用var聲明
- 不能使用delete關鍵字來刪除全局變量
- 函數(shù)的形參列表中不能出現(xiàn)同名的參數(shù)
- 在對象內部不能出現(xiàn)相同的屬性
- 禁止使用八進制
- 禁止使用with語句
- 禁止使用eval 和arguments作為標識符( 標識符就是不要這讓兩個參數(shù)作為變量使用 不然會報錯 !)
- 在函數(shù)調用的時候碍讯,修正了函數(shù)內部this的指向
- 示例代碼 :
<script>
"use strict";
var obj1 = {
name:"張三",
showName:function(){
console.log(this);
}
}
obj1.showName(); //obj1 this--->obj1
var showName = obj1.showName;
showName(); //this丟失的問題 this--->window(非嚴格)|undefined(嚴格)
obj1.showName.call(null);
//在嚴格模式下,函數(shù)內部的this綁定誰由第一個參數(shù)決定扯躺,如果沒有傳遞那么是undefined捉兴,如果傳入的值是null蝎困,那么綁定的就是null
</script>
- 禁止使用callee | caller
- arguments在函數(shù)內部的表現(xiàn)和非嚴格模式不同
1.arguments 接收實參的值
2.值類型&&引用類型的數(shù)據作為函數(shù)的參數(shù)傳遞,在非嚴格模式下倍啥,arguments和形參共享一份數(shù)據
3.重新設置了形參的值禾乘,arguments的值也會發(fā)生改變,在嚴格模式下虽缕,arguments和形參是獨立的始藕,他們之間沒有關系,修改了形參的值對arguments沒有影響的
- 示例代碼 :
<script>
"use strict";
function funcName(paramStr){
console.log(paramStr);
console.log(arguments[0]);
//重新設置形參的值
paramStr = "測試的字符串";
console.log(arguments[0]);
}
var str = "demoStr";
funcName(str);
function funcName02(obj)
{
console.log(obj);
console.log(arguments[0]);
//重新設置obj的值
obj = {age:20};
console.log(obj);
console.log(arguments[0]);
}
var obj = {
name:"張三"
};
funcName02(obj);
</script>
嚴格模式的作用域
寫在當前作用域的最頂端
作用范圍
- script標簽 只對當前的標簽有影響氮趋,僅僅設置當前的標簽為嚴格模式
- 函數(shù)內 那么只對當前的函數(shù)作用域有效
- 示例代碼 :
<script>
// "use strict"; 位置01 對f1和f2都有效
function f1(){
// "use strict"; 位置02 對f1有效f2無效
//a = 10;
}
function f2(){
// "use strict"; 位置03 對f2有效f1無效
b = 20;
}
f1();
f2();
</script>
作用域
某個變量有( 起 ) 作用的范圍
塊級作用域, 在別的語言里有塊級作用域, 但是在js中沒有塊級作用域
js中的作用域
- script構成了全局作用域
- 在js中函數(shù)是唯一一個可以創(chuàng)建作用域的對象
詞法作用域 - 動態(tài)作用域
- 詞法作用域:在變量聲明的時候伍派,它的作用域就已經確定了
- 動態(tài)作用域:在程序運行的時候,由程序的當前上下文(執(zhí)行環(huán)境)決定的
- js屬于詞法作用域
詞法作用域的訪問規(guī)則:
- 先在當前作用域中查找剩胁,如果找到就直接使用,如果沒有找到诉植,那么就到上一級作用域中查找,如果還沒有找到那么就重復這個查找的過程昵观,直到全局作用域
變量和函數(shù)提升
js的執(zhí)行順序
- 預解析階段 變量和函數(shù)的提升(聲明)
- 具體的執(zhí)行階段
- 變量和函數(shù)的提升
- 示例代碼 :
<script>
console.log(a); //undefined ?
var a = 10;
f1();
function f1(){
console.log("f1");
}
</script>
- 變量和變量同名的情況:后面的變量會把前面的變量覆蓋
- 示例代碼 :
<script>
// var n1 = "n1";
// console.log(n1); //n1
//
// function test(){
// console.log(n1);
// }
//
// test(); //n1
// var n1 = "new n1";
// console.log(n1); //new n1
// test(); //new n1
// 模擬變量和函數(shù)的提升
var n1;
function test(){
console.log(n1);
}
var n1;
n1 = "n1";
console.log(n1); //n1
test(); //n1
n1= "new n1";
console.log(n1); //new n1
test(); //new n1
</script>
- 函數(shù)和函數(shù)同名的情況
- 示例代碼 :
<script>
f1(); //10 ? 20
function f1(){
console.log(10);
}
f1(); //20
function f1(){
console.log(20);
}
f1(); //20
</script>
- 函數(shù)和變量同名的情況:可以理解為函數(shù)聲明提升而變量的聲明不提升(忽略)
- 示例代碼 :
<script>
console.log(demo); //
var demo = "我是字符串";
function demo(){
console.log("我是函數(shù)");
}
console.log(demo); //
//......
var demo;
function demo(){
console.log("我是函數(shù)");
}
console.log(demo); //函數(shù)
demo = "我是字符串";
console.log(demo); //我是字符串
</script>
<script>
console.log(test); //函數(shù)
function test(){
console.log("我是函數(shù)");
}
var test = "我是帥哥";
console.log(test); //
///////變量聲明(和函數(shù)同名的)不會提升
function test(){
console.log("我是函數(shù)");
}
console.log(test); //
var test = "我是帥哥";
console.log(test);
</script>
注意 : 如果是函數(shù)的表達式,那么在做函數(shù)聲明提升的時候,僅僅只會把var 變量的名稱(函數(shù))提升到當前作用域的最頂端
作用域鏈
- js中函數(shù)可以創(chuàng)建作用域
- js中的函數(shù)中可以聲明函數(shù)
- 函數(shù)內部的函數(shù)中又可以聲明函數(shù)
- 以上,會形成一個鏈式的結構,這個是作用域鏈
- 示例代碼 :
<script>
var a = 10;
function f1(){
function f2(){
var d = "demoD";
}
}
function f3(){
function f4(){
}
var b = "demoB";
function f5(){
var c = "demoC"
}
}
</script>
圖解
**作用域鏈**