當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
JavaScript高级部分概念用法
生活随笔
收集整理的這篇文章主要介紹了
JavaScript高级部分概念用法
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
一、執(zhí)行上下文
也稱為可執(zhí)行代碼和執(zhí)行上下文 執(zhí)行代碼:1.全局代碼 2.函數(shù)代碼 3.eval代碼 eval("var a = 200;console.log(a)") 執(zhí)行上下文 - Context 所處的一個環(huán)境,環(huán)境不同含義也隨著改變了 當可執(zhí)行代碼執(zhí)行的過程中,都會產生一個可執(zhí)行環(huán)境 在執(zhí)行完之后,執(zhí)行上下文的環(huán)境也隨著銷毀 執(zhí)行上下文中變量存在于: 變量對象:VO - var 聲明的一個屬性值 - 全局 活動對象:AO - 相對于函數(shù)創(chuàng)建的對象中的一個聲明 - 局部 - 隨執(zhí)行完后銷毀 不管變量在什么地方聲明,都會在函數(shù)一運行就聲明一個函數(shù)中的變量 變量提升:指一個函數(shù)上下文創(chuàng)建時,函數(shù)中的所有變量都會隨函數(shù)的創(chuàng)建提升var x = 100;var outFunc = function(){x++;console.log(x);//NaNvar x = 200;}outFunc();console.log(x);//100 函數(shù)中 x 聲明提前,但是賦值并沒有提前,所有此時的x為undefined,undefined進行運算結果就為NaNvar outFunc = function(){var a = 100;var innerHtml = function(){var b = 200;a = b;//a替換了outFunc()中a var a = 100的值 此時a = 200; // c = a;}innerHtml();console.log(["inner:",a]);//200 } outFunc();//該函數(shù)在運行完后函數(shù)中的變量隨之銷毀 console.log("outer:",a);//not defined二、作用域 作用域鏈
作用域:即為代碼的作用范圍 作用域鏈:函數(shù)的變量不使用var聲明的情況下,聲明變量會一直往上查找該變量的值,直到全局變量還沒有就創(chuàng)建一個全局變量 Scope對象 - 存放上一層中的對象引用 - 屬于某一個函數(shù)的屬性,當函數(shù)一創(chuàng)建就已經有該函數(shù)的scope對象引用了 每個函數(shù)都包含自己本身的VO、Scope對象、作用域鏈對象 var food = "包子"; var eat = function(){console.log(food);//包子 } (function(){var food = "油條";eat() })var foo = 1; function bar(){if(!foo){var foo = 10;//foo會變量提升到bar函數(shù)中,但值不會提升此時提升的foo為undefined !foo 剛好滿足條件}console.log(foo); } bar();var a = 1; function b(){a = 10 ;//a = a()return;function a(){}//會變量提升到函數(shù)的前面 } b(); console.log(a);var f = true; if(f === true){var a = 10; } function fn(){var b = 20;c = 30; } fn(); console.log(a);//10 console.log(b);//not definnd console.log(c);//30if('a' in window){var a = 10;//變量提升至if判斷外,但值不會提升;沒有var 不會先變量提升會先判斷是否進入判斷 } console.log(a);//10var a = b =3; (function(){var a = b = 5;//var a = 3; b = 5 })(); console.log(a);//3 console.log(b);//5var foo = 'A'; console.log(foo); //A var foo = function(){console.log('B'); } console.log(foo); //function(){console.log('B');} foo(); //B function foo(){ //函數(shù)是在最開始的時候就存在了,但在var foo 聲明后被覆蓋了,已經被提升;會影響代碼的上下順序console.log('C'); } console.log(foo); //function(){console.log('B');} - foo(); //Bvar a = 1; function b(){console.log(a);//undefineda = 2;console.log(a);//2var a = 3;console.log(a);//3 } console.log(a);//1 b(); console.log(a);//1//閉包相關的函數(shù)值 var x = 100; var y = 200; function funcA(x){var y = 201;function funcB(){console.log(x);//101console.log(y);//201}return funcB; } var f = funcA(101); f();三、this關鍵字
this 也稱為當前對象,是用于對象當中,屬于第一人稱,所處的環(huán)境不一樣指代的含義也不同 如果在對象的方法中只要在嵌套的函數(shù)中的this就不會再指向當前對象中的this了 比如: var name = "張三"; var func = function(){console.log(this.name);//此時的this指向的是全局變量 } func(); fnnc.apply(); func.call() var obj = {name:"王五",func:function(){console.log(this.name);//此時的this 指向的是對象中的name(function(){console.log(this.name);//此時的this指向的不是對象的name,而是全局變量})()} } obj.func();改變this指向的方法: 1.call 2.apply 兩者的作用是相同的,可以幫助完成方法的調用,默認this指向為全局,要想訪問嵌套對象,就將其賦值給一個變量 call() Or apply()可以改變this的對象,第一個參數(shù)是不能省的 區(qū)別: var sum = function(a,b){console.log(a+b)} sum.call(null,100,200) - 采用的是參數(shù)列表 sum.apply(null,[100,200]) - 采用的是數(shù)組***練習*** var myObject = {foo:"bar",func:function(){var self = this;console.log(this.foo);//barconsole.log(self.foo);//bar(function(){console.log(this.foo);//undefinedconsole.log(self.foo);//bar})()} } myObject.func();var user = {count:1,getcount:function(){return this.count;} } console.log(user.getcount());//1 var func = user.getcount;//func就代表user.getcount這個函數(shù) console.log(func());//undefined - func()已經成為全局,全局中沒有count這個變量,所以值為undefined四、閉包 - closure
閉包:是指能夠訪問函數(shù)內部變量的函數(shù),定義在函數(shù)內部的函數(shù)。 一個函數(shù)引用了外部的自由變量,那么這個函數(shù)就叫閉包,被引用的函數(shù)和引用的函數(shù)是一同存在的。 自由變量 - 跨作用域的變量或父級的變量 函數(shù)必須引用外部變量,函數(shù)還必須被引用才能成為閉包 優(yōu)點:可以把一個局部變量存在的時間延長,進行持續(xù)保存 缺點:如果大量的使用閉包,持續(xù)保存的變量會一直占有內存,造成內存的浪費 常用:事件處理常常會使用到閉包var lis = document.getElementsByTagName("li"); for(var i = 0;i<lis.length;i++){//方法實現(xiàn)一(function(index){//阻止閉包lis[index].onclick = function(){console.log("這是選中的地"+(index+1)+"項");}})(i)//方法實現(xiàn)二var func = function(index){lis[index].onclick = function(){console.log("這是選中的地"+(index+1)+"項");}}func(i); }//閉包練習 function Foo(){var i = 0;return function(){console.log(i++);//i++先賦值再運算} } var f1 = Foo(); var f2 = Foo(); f1();//0 f2();//0 f2();//1五、面向對象 - OO - Object Oriented
語言分類大致分為兩大類 - 范式 1.命令式 - 通過語言告訴計算機應該如何做事情 比如:java、C語言(為程序語言的發(fā)展做出貢獻) 命令式的兩種思想:1.1.面向過程 - 將過程逐一分解為一個一個的步驟執(zhí)行 - 計算機的思維方式為主體缺點:人的思維有限,如果程序實現(xiàn)的過程很復雜,人會不能完全考慮 1.2.面向對象 - 本身就是人的思考方式,人的思維為主體,從自身角度出發(fā) - 特征、行為 - 萬物皆對象,對象因關注而產生2.聲明式 - 告訴計算機我想要什么,然后計算機進行相關的動作,然后計算機自己進行運算得到我想要的結果 比如:Css 聲明式的三大類:2.1.領域特定語言 - DSL - 在特定范圍的語言 - HTML、Css、SQL、正則表達式2.2.函數(shù)式編程 - 類似公式,計算機就會按照這個公式進行計算并返回結果 與命令式編寫相比,函數(shù)式編程更為精簡,能夠完善命令式編程的一些缺陷 - lisp、Haskell2.3.邏輯編程 - prolog - 記日志比較好的方法構建對象的兩種方式: 1.基于類的面向對象 - 擁有相同屬性的劃分為一類,類是對象的抽象,對象是類的實例 2.基于原型的面向對象 - JavaScript原型就有一個Object對象,通過一個原型克隆一個對象 好處:足夠靈活 缺點:隨意性太強,對于初學者容易出錯 面向對象三大特征: 1.封裝 - 需重點了解 - 指實現(xiàn)細節(jié)隱藏起來的過程就是封裝 優(yōu)點: - 但還需要考慮參數(shù)的問題1.1.隱藏實現(xiàn)的細節(jié)1.2.重用 - 不變的整合在一起,變化的作為參數(shù)JavaScript中屬性都應為私有,方法可以為公共 - 由我們自己控制pulic - 公共,其他方法可以訪問private - 私有,只能自己能夠訪問set/get - 訪問器/修改器var Student = function(name,age,gender){this.name = name;var _age = age;//添加 _ 可將變量變?yōu)樗接凶兞?#xff0c;外部不能隨意訪問var _gender = gender;if(!Student._init){Student.prototype.getAge = function(){return _age;}Student.prototype.setAge = function(age){if(age > 20 && age < 30){_age = age;console.log(_age);}else{console.log("年齡修改不能在 20 - 30 之外");}}Student.prototype.getGender = function(){return _gender;}Student.prototype.setGender = function(gender){_gender = gender;console.log(_gender);}}Student._init = true;}var stu = new Student("張飛",20,"男");stu.name = "關羽";stu.setAge(31);console.log(stu.getAge());console.log(stu.getGender());stu.setGender("無");2.繼承 - 存在于有父與子的關系中 - 出現(xiàn)率較高 - 指采用一個對象的功能并且能夠添加新的功能優(yōu)點:2.1.復用2.2.擴展缺點:如果繼承設計的不夠完善,會致使變得復雜,難以操控繼承的3種方法:1.對象冒充法 - instanceof - 判斷是否為繼承2.原型鏈 - 將自己的原型改變?yōu)楦讣壍膶ο?.混合方式 - // 1.對象冒充法/*var People = function(name){this.name = name;}People.prototype.intro = function(){console.log("HI,我是"+this.name);}var ChinesePeople = function(name){this.inhert = People;this.inhert(name)delete this.inhert;}var info = new ChinesePeople("張三");console.log(info.name);console.log(info instanceof ChinesePeople);*/// 2.原型鏈 /* var People = function(name){this.name = name;}People.prototype.intro = function(){console.log("HI,我是"+this.name);}var ChinesePeople = function(name){}ChinesePeople.prototype = new People("張三");ChinesePeople.prototype.area = function(){console.log("我是中國人");}var info = new ChinesePeople("張三");console.log(info.name);console.log(info instanceof ChinesePeople);info.intro();info.area();*/// 3.混合/*var People = function(name){this.name = name;}People.prototype.intro = function(){console.log("HI,我是"+this.name);}var ChinesePeople = function(name){People.call(this.name);}ChinesePeople.prototype = new People("張三");ChinesePeople.prototype.area = function(){console.log("我是中國人");}var info = new ChinesePeople("張三");console.log(info.name);console.log(info instanceof ChinesePeople);info.intro();info.area();*/ 3.多態(tài) - JavaScript本身就是一個多態(tài)的行為var Student = {"name":"張飛","age":20,"learn":function(){console.log(this.name+"學習JavaScript")} } Student.gander;//訪問的屬性不存在 值為 undefined Student.learn(); Student.name; Student["name"]; Student["lea"+"rn"];//動態(tài)的屬性值使用中括號或者字符串拼接//構造函數(shù) var Student = function(name,age){this.name = name;this.age = age;this.learn = function(){console.log(this.name+" - "+this.age);var that = this;(function(){console.log(that);}())} } var stu1 = new Student("張飛",20);//stu1 為一個對象 var stu2 = new Student("劉備",21); Student.prototype.gander = "男";//在原型中添加一個性別的屬性 Student.prototype.play = function(){//在原型中創(chuàng)建一個play 的方法console.log(this.name+" - "+this.age+" - "+"喜歡玩游戲"); } stu1.learn(); console.log(stu1.gander); stu1.play(); stu2.learn(); Studetn.prototype;//可以改變一個對象真正的原型,但是不能多次調用 stu1.__proto__; //只是更改了stu1的引用原型,而不是本身的原型,只是對象的一個屬性,可以通過屬性一層一層的訪問到對象的原型對象 → 自定義對象原型 → Object對象 → Object原型 → Nullif(!Student._int){//首先判斷Student._int是否為假,Student._int事先不存在即為假,進入判斷,Student._int變?yōu)檎?#xff0c;不在進入判斷,該判斷這樣就只能判斷一次Student.prototype.learn = function(){console.log(this.name+" - "+this.age);}Student.prototype.play = function(){//在原型中創(chuàng)建一個play 的方法console.log(this.name+" - "+this.age+" - "+"喜歡玩游戲");}Student._int = true; }兩個運算符:new - 創(chuàng)建對象; delete - 刪除屬性 - delete.stu1.name;//stu1中的name屬性就被刪除了,只能刪除原型創(chuàng)建的而不能刪不是原型創(chuàng)建的屬性 兩個語句:with - 性能有一定的問題,盡量不使用; for..in - 不拿來循環(huán)數(shù)組;var stu1 = new Student("張飛",20);//stu1 為一個對象 var stu2 = new Student("劉備",21); for(var key in stu1){console.log([key,stu1[key]]); }轉載于:https://www.cnblogs.com/1039595699TY/p/5642080.html
總結
以上是生活随笔為你收集整理的JavaScript高级部分概念用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (王道408考研操作系统)第二章进程管理
- 下一篇: Linux系统编程6:入门篇之如何拿下g