摘要:中的多態不存在重載,方法名一樣,后面的會把前面的覆蓋掉,最后只保留一個方法。
1、查找作用域
當前函數在哪個作用域下定義的,那么他的上級作用域就是誰 ?, 和函數在哪執行沒有任何關系
//作用域實例 var num = 12; function fn(){ var num = 120; return function(){ console.log(num); } } var f = fn(); f();//->120 (function(){ var num = 1200; f();//->120 }())2、++i 和 i++的區別
//實例說明 var i = 5; 5 + i++ //->10 //i++ 是先運算i本身再加1 //======== var j = 5; 5 + (++j) //->11 //++j 是本身先加1再運算 //面試題 var n = 2; var num = 5 + (++n) + (n++) + (n++) + (++n); // - > 213、預解釋
在js執行之前,瀏覽器首頁會把帶var和function的關鍵字進行提前申明或定義;var(只是提前申明) function(提前申明+定義)
注:如果在全局作用域下定義一個 num = 10(沒有var)和帶var 是有區別的
//實例說明 console.log(num);//->undefined console.log(num1);//->num1 is not defined var num = 10;//->先預解釋->window.num = 10 num1 = 10;//->window.num1 = 10 //不帶var的num1沒有提前申明所以報is not definend
預解釋面試題
//實例1 function a(b){ alert(b); function b(){ alert(b); } b(); } a(1); //1->alert(b函數),2->alert(函數) //實例2 alert(a); //undefined var a = 0; alert(a); //0 function fn(){ alert(a); //0;因為沒var, 所以這里的a會被看作是全局的,往上查找,找到a=0,所以是0,如果全局也沒有就會報錯 a = 2; alert(a); //2 } fn() alert(a); //2,fn把這全局的a修改了 //實例34、區分this
函數執行,首先看函數名是否有".",有的話,"."前面是誰this就是誰;沒有的話this就是window
自執行函數的this永遠是window
給元素的某一個事件綁定方法,當事件觸發的時候,執行對應的方法,方法中的this是當前的元素
構造函數中的this是這個類的實例
this還可以通過call、apply、bind來改變
function fn(){ console.log(this); } var obj = { name:"李四", writeJs:fn } obj.writeJs();//this->obj var fn = obj.writeJs; fn();//this->window function sum() { fn();//this->window } sum(); (function() { fn();//this->window )() document.getElementById("div").onclick = fn;//this->#div document.getElementById("div").onclick = function() { //this->#div fn();//this->window }
this綜合實例(360面試題)
var num = 20; var obj = { num: 30, fn: (function (num) { this.num *= 3; num += 15; var num = 45; return function () { this.num *= 4; num += 20; console.log(num); } }) (num) } var fn = obj.fn; fn();//65 obj.fn();//855、單例模式
描述同一個事物(同一個對象)的屬性和方法放在一個內存空間下,起到分組的作用,這樣不同事物之間的屬性名相同,相互也不會發生沖突,我們把這種分組編寫代碼的模式叫做“單例模式”;
var obj = { name: "張三", age: "18", writeJs: function(){ console.log("my is "+this.name+" can write js"); } } obj.writeJs();
注:obj又叫做“命名空間”,單例模式項目開發經常使用,我們可以使用單例模式進行模塊化開發;6、工廠模式
單例模式雖然能解決分組作用,但是不能實現批量生產,屬于手工作業模式;
工廠模式->“函數的封裝”,“低耦合高內聚”:減少頁面中的冗余代碼,提高代碼的重復利用
function createJs(name,age){ var obj = {}; obj.name = name; obj.age = age; obj.writeJs = function(){ console.log("my is "+ this.name +" can write js"); } return obj; } var zhangsan = createJs("張三","18"); zhangsan.writeJs();
所有的編程語言都是面向對象開發的。就有類的繼承、封裝、多態
繼承:子類繼承父類的屬性和方法
封裝:函授的封裝
多態:當前方法的多種形態
后臺語言中的多態包含重載和重寫。js中的多態不存在重載,方法名一樣,后面的會把前面的覆蓋掉,最后只保留一個方法。(js中有一個類似重載但不是重載:可以根據傳遞的參數不一樣,實現不同的功能)重寫:子類重寫父類的方法
7、構造函數模式構造函數是通過new關鍵詞創建一個實例;
var ex = new CreateJs();其中ex就是CreateJs的實例,生成CreateJs這個類;
Js中所有的類都是函數數據類型,它通過new執行變成一個類,但是他本身也是個普通的函數
Js中所有的實例都是對象數據類型
在構造函數模式中,類中出現的this.xxx=xxx中this是當前類的一個實例
不同實例之間方法不一樣(下例)
在構造函數模式中,瀏覽器會默認把我們的實例返回(返回對象數據類型的值);如果我們手動寫return返回;
如果ruturn是一個基本數據類型的值,當前實例不變,例如:return 10;
如果return是一個引用數據類型的值,當前實例會被自己返回的值替換,例如:ruturn {name:"張三"}
檢測某個實例是否屬于這個類 instanceof;
zhangsan instancaof CreateJs->true
in:檢測某一個屬性是否屬于這個對象 attr in object,不管是私有屬性還是共有屬性,只要存在,用in檢測都是true
hasOwnProperty:用來檢測某一個屬性是否為這個對象的私有屬性,這個方法只能檢測私有屬性 obj.hasOwnProperty(attr);
function CreateJs(name,age) { this.name = name; this.age = age; this.writeJs = function() { console.log("my is "+ this.name +" can write js"); } } var zhangsan = new CreateJs("張三","18"); zhangsan.writeJs(); var lisi = new CreateJs("李四","20"); lisi.writeJs(); zhangsan.writeJs === lisi.writeJs//false8、原型鏈模式
每一個函數數據類型(普通函數、類)都有一個天生自帶的屬性:prototype(原型),并且這個屬性是一個對象數據類型的值;
prototype上瀏覽器天生給它加了個屬性constructor(構造函數),屬性值是當前函數(類)本身;
每一對象數據類型(普通對象、實例、prototype..)天生自帶一個屬性__proto__,屬性值是當前實例所屬類的prototype(原型)
Object是Js中所有對象的基類,Object.prototype上沒有__proto__這個屬性
function CreateJs(name,age) { this.name = name; this.age = age; } CreateJs.prototype.writeJs = function() { console.log("my is "+ this.name +" can write js"); } var zhangsan = new CreateJs("張三","18"); zhangsan.writeJs(); var lisi = new CreateJs("李四","20"); lisi.writeJs(); zhangsan.writeJs === lisi.writeJs//true
通過對象名.屬性名獲取屬性值的時候,首先在對象的私有屬性找,如果私有屬性存在,則獲取的是私有屬性值;
如果私有沒有,則通過__proto__找到所屬類的原型,原型上存在的話獲取的是公有的屬性值;
如果原型上也沒有,則繼續通過原型上的__proto__繼續向上查找,一直找到Object.protoype為止
9、call、apply、bind使用call、apply的區別
對于 apply、call 二者而言,作用完全一樣,只是接受參數的方式不太一樣。
func.call(this, arg1, arg2); func.apply(this, [arg1, arg2])
實例:
//1、數組之間追加 var array1 = [12 , "foo" , {name "Joe"} , -2458]; var array2 = ["Doe" , 555 , 100]; Array.prototype.push.apply(array1, array2); /* array1 值為 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */ //2、獲取數組中的最大值最小值(數組中本身沒有max方法) var numbers = [5, 458 , 120 , -215 ]; var maxInNumbers = Math.max.apply(Math, numbers), //458 maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458 //3、檢驗數據類型 Object.prototype.toString.call(obj) === "[object Array]" ; //4、類數組轉數組 var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
bind
bind()方法會創建一個新函數,稱為綁定函數,當調用這個綁定函數時,綁定函數會以創建它時傳入 bind()方法的第一個參數作為 this,傳入 bind() 方法的第二個以及以后的參數加上綁定函數運行時本身的參數按照順序作為原函數的參數來調用原函數
var bar = function(){ console.log(this.x); } var foo = { x:3 } bar(); // undefined //bind是先綁定this和參數,不執行本身函數 //call和apply是綁定this和參數后立即執行本身函數 var func = bar.bind(foo); func(); // 310、計算數組中最大值
var arr = [12,43,2323,455,23,5]; arr.sort(function(x,y) { return x-y; }) var max = arr[arr.length-1]; var arr1 = [123,34,54,23,56,1]; var max = arr1[0]; for(var i = 0;i < arr1.length;i++ ) { var cur = arr1[i]; if(cur>max) { max = cur[i]; } } var arr2 = [23,43,123,341,3233]; var max = Math.max.apply(null,arr2); var arr3 = [567,23,42,45,1,98]; var max = eval("Math.max("+arrr.toString()+")");11、數組求平均數
function avgFn() { var arr = Array.prototype.slice.apply(arguments); arr.sort(function(x,y) { return x - y; }) arr.shift() arr.pop(); var arg =(eval(arr.join("+"))/arr.length).toFixed(2) return arg; } avgFn(68,97,97,91,99.1,89.5,98.23) function avgFn() { var arr = [].sort.call(arguments,function(x,y) { return x-y; }); [].shift.call(arguments); [].pop.call(arguments); return (eval([].join.call(arguments,"+"))/arguments.length).toFixed(2); } avgFn(68,97,97,91,99.1,89.5,98.23)12、sort的深入
arr.sort();只能默認排序10以內的數字和26字母排序
var arr = [1,3,4,65,23,32,43,567]; arr.sort();//log->[1, 23, 3, 32, 4, 43, 567, 65] var arr1 = [2,5,6,4,9,1.2,0.9]; arr1.sort();//log->[0.9, 1.2, 2, 4, 5, 6, 9] var arr2 = ["a","y","b","t","p","c"]; arr2.sort();//log->["a", "b", "c", "p", "t", "y"]
arr.sort(function(){})傳遞參數
var arr = [1,3,4,65,23,32,43,567]; arr.sort(); /** *執行中a和b的值 *a b *1 3 *3 4 *4 65 *65 23 *4 23 *65 32 *23 32 *65 43 *32 43 *65 567 *a - b > 0 a和b調換位置 *a - b <= 0 位置不變 */ arr.sort(function(a,b){ return a - b; }) arr.sort(function(a,b){ return b - a; })
利用localeCompare字母排序
localeCompare第一個字符串字母按照26個字母順序排序,如果第一個字母相同會按照第二個字母排序以此類推,漢字會先轉換成拼音再排序,如果漢字同音會按照漢字unicode順序排
"a".localeCompare("b") //-1 "c".localeCompare("b") //1 var arr = [{name:"wangwu",age:17},{name:"lisi",age:17},{name:"dahuang",age:21}]; arr.sort(function(a,b){ return a.name.localeCompare(b.name); }) //[{name:"dahuang",age:21},{name:"lisi",age:17},{name:"wangwu",age:17}] var arr = [{name:"小呂",age:17},{name:"老王",age:17},{name:"大黃",age:21}]; arr.sort(function(a,b){ return a.name.localeCompare(b.name); }) //[{name:"大黃",age:21},{name:"老王",age:17},{name:"小呂",age:17}]13、DOM回流(重排 reflow)、DOM重繪、DOM映射
DOM回流:DOM樹渲染完畢以后,只要頁面中的HTML結構發生變化(增加刪除元素、位置發生變化),瀏覽器都要重新計算一遍最新的DOM結構,重新對當前頁面進行渲染;
DOM重繪:DOM樹位置不發生變化,如元素的顏色背景發生變化,會只針對這個元素渲染,不渲染整個頁面
DOM映射:頁面中的標簽和Js中獲取到的元素對象(元素集合)是緊緊綁定在一起的,頁面中HTML結構改變了,Js不需要重新獲取,集合里面的內容也會跟著自動改變
14、js中數據綁定的方法1、動態創建節點方式
var oUl = document.getElementById("ul"); var oLi = document.createElement("li"); oLi.innerHTML = "hello world"; oUl.appendChild(oLi);
2、字符串拼接的方式
var oUl = document.getElementById("ul"); var str = ""; for(var i = 0;i < arr.length; i++) { str += "
3、文檔碎片方式
var oUl = document.getElementById("ul"); var frg = document.createDocumentFragment();//創建一個文檔碎片 var oLi = document.createElement("li"); oLi.innerHTML = "hello world"; frg.appendChild(oLi); oUl.appendChild(frg); frg = null;//手動清空碎片15、正則 什么是正則
它是一個規則,用來處理字符串的規則。正則的創建
1. 字面量創建
var reg = /d/;
2. 實例創建
var reg = new RegExp("d");元字符
每一個正則表達式都是由元字符和 修飾符組成
具有特殊意義的元字符
:轉義后面字符所代表的含義
^ :以某一個元字符開始
$ :以某一個元字符結束
n :匹配一個換行符
. :除了n以外的任意字符
() :分組
x|y :x或y中的一個
[xyz] :x或者y或者z中的任何一個字符
[a-z] :a-z之間的任意字符
[^a-z]:除了a-z之間的任何字符 d :一個0-9之間的任何數字 :匹配一個邊界符 w :數字字母下劃線中的任意一個字符 s:匹配一個空白字符 空格、制表符、換頁符...
代表出現次數的量詞元字符
* :出現0到多次
+ :出現1到多次
? :出現0到1次
{n} :出現n次
{n,} :出現n到多次
{n,m} :出現n到m次
()分組的作用改變x|y的優先級
var reg = /^18|19$/; //18、19、181、189、119、819、1819....true var reg = /^(18|19)$/; //18、19true
分組引用
var reg = /^(w)1(w)2$/; reg.test("aabb")//true reg.test("abcd")//false //1代表和第一個分組出現一模一樣的內容 //2代表和第二個分組出現一模一樣的內容 //去除重復的字符 var str = "aaaabbbbccccffffdffffdssss440000008888"; str.replace(/(w)1+/g,"$1"); //"abcds408"
分組捕獲
正則在捕獲的時候,不僅僅把大正則匹配到,而且還可以把小分組的內容捕獲到
var reg = /^(d{2})(d{4})(d{4})(d{4})d{2}(d{1})[d|X]$/ var arr = reg.exec("100604198805112411"); //["100604198805112411", "10", "0604", "1988", "0511", "1"] //100604198805112411大正則匹配的內容 //"10", "0604", "1988", "0511", "1"小分組匹配
[](1)、在中括號中出現的所有的字符都是代表本身意義的字符(沒有特殊的含義)(2)、中括號不識別兩位數
var reg = /^[.]$/; reg.test("1");//false reg.test(".");//true var reg = /[12]/; //1||2 不是12 var reg = /^[21-57]$/; //2||1-5||7中的任意一個
//年齡介于[16-58] var reg = /^(1[6-9]|[2-4]d|5[0-8])$/; //簡單的驗證郵箱 var reg = /^[w.-]+@[da-zA-Z]+(.[a-zA-Z]{2,4}){1,2}$/; //中國標準真實姓名2-4位漢字 var reg = /^[u4e00-u9fa5]{2,4}$/; //身份證號碼 //100604198805112411 //10(省)0604(市區縣)19880511(出身年月)24(沒用)1(奇數男、偶數女)1(0-9||X) var reg = /^(d{2})(d{4})(d{4})(d{4})d{2}(d{1})[d|X]$/;正則的捕獲exec
捕獲的內容是個數組
var reg = /d+/; reg.exec("ducen23niubi21"); //0:"23",index:5,input:"ducen23niubi"
正則捕獲的特點
懶惰型:每一次執行exec只捕獲第一個匹配的內容,在不進行任何處理的情況下,在執行多次捕獲,捕獲的還是第一個匹配的值
var reg = /d+/ reg.lastIndex//0 res = reg.exec("ducen23niubi12")//["23"] reg.lastIndex//0 res = reg.exec("ducen23niubi12")//["23"]
//解決懶惰性,在正則后加修飾符g var reg = /d+/g reg.lastIndex//0 res = reg.exec("ducen23niubi12")//["23"] reg.lastIndex//7 res = reg.exec("ducen23niubi12")//["12"] reg.lastIndex//14 res = reg.exec("ducen23niubi12")//null
貪婪性:正則每一次捕獲都是按照匹配最長的結果
var reg = /d+/; res = reg.exec("ducen2017niubi12"); //捕獲到的是["2017"]而不是2 //解決正則的貪婪性(在量詞元字符后面添加一個?) var reg = /d+?/; res = reg.exec("ducen2017niubi12"); //捕獲的是["2"];
++?在正則中有很多作用,放在一個不同的元字符后面代表出現0-1次 /d?/(數字出現一次或不出現);放在一個量詞的元字符后面是取消捕獲的貪婪性++
正則的修飾符(g、i、m)var reg = /d/gim //g:全局匹配 //i:忽略大小寫匹配 //m:多行匹配
var reg = /d+/g var arr = [] res = reg.exec("ducen23niubi12"); while(res) { arr.push(res[0]); res = reg.exec("ducen23niubi12") } arr//["23", "12"]字符串中的match方法
把所有和正則匹配的字符都獲取到
var reg = /d+/g var arr = "ducen23niubi12".match(reg); arr//["23", "12"]
雖然在當前的情況下match比我們的exec更加簡便一些,但是match中存在一些自己處理不了的問題:在分組捕獲的情況下,match只能捕獲大正則匹配的內容,而對小正則捕獲的內容無法獲取
字符串中的replace方法var str = "ducen2015ducen2016"; str.replace("ducen","huming"); //"huming2015ducen2016" str.replace(/ducen/g,function(arg){ console.log(arguments); return "huming"; }) //"huming2015huming2016" str.replace(/ducen(d+)/g,function(arg){ console.log(arguments) console.log(arguments[1])//2015 2016 獲取小正則 })
replace中的匿名函數執行次數,取決于正則捕獲的次數
每一次執行匿名函數里面傳遞的參數值arguments和我們自己通過exec捕獲到的結果是非常類似的(即使正則有分組,我們也可以通過arguments獲取)
return:你返回的結果是啥,就相當于把當前大正則捕獲的內容替換成返回的內容
var arr = ["零","壹","貳","叄","肆","伍","陸","柒","捌","玖"] var s = "20170401"; s.replace(/d/g,function(){ return arr[arguments[0]] })
//1 "2343289".replace(/^(d{1,3})((?:d{3})+)$/,function(){ return arguments[1]+"," + arguments[2].replace(/(d){3}(?!$)/g,function(){ return arguments[0]+ "," }) }) //2 var str = "2343289"; str.replace(/(d)(?!$)/g,function(res,i){ if((str.length-i-1)%3==0) { return res+ "," }else{ return res; } }) //3 var str = "2343289"; str = str.split("").reverse().join(""); str = str.replace(/(d{3})/g,"$1,"); str.split("").reverse().join("");正則中?的用法
在量詞后面代表0到1次(?)
var reg = /^(+|-)?d+(.d+)?$/;
匹配不捕獲(?:)
var reg = /^(?:+|-)?d+(.d+)?$/
取消正則貪婪捕獲,把?放在量字后面(?)
var reg = /d+/; res = reg.exec("ducen2017niubi12"); //捕獲到的是["2017"]而不是2 //解決正則的貪婪性(在量詞元字符后面添加一個?) var reg = /d+?/; res = reg.exec("ducen2017niubi12"); //捕獲的是["2"];
正向預查、負向預查(條件)
(?!n)->匹配任何其后緊接指定字符串 n 的字符串。 (?=n)->匹配任何其后沒有緊接指定字符串 n 的字符串。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82391.html
摘要:小弟在前端摸爬滾打一段時間,發現前端的比較好的文檔比較分散,特別是中文的,我平時都是收藏在瀏覽器里,以后有好的教程和綜合性的文檔我會更新到這里。小組中文文檔,很全。 小弟在前端摸爬滾打一段時間,發現前端的比較好的文檔比較分散,特別是中文的,我平時都是ctrl+D收藏在瀏覽器里,以后有好的教程和綜合性的文檔我會更新到這里。一則可以做個記錄,防止丟失。二則有需要的朋友可以來我這里找一找。 ...
摘要:給初學者的印象總是那么的雜而亂,相信很多初學者都在找輕松學習的途徑。通常學了很久的基礎之后,變量函數對象你也都略知一二,但一到公司開發項目的時候,卻又難以下手。 Js給初學者的印象總是那么的雜而亂,相信很多初學者都在找輕松學習Js的途徑。在這里給大家總結一些學習Js的經驗,希望能給后來的學習者探索出一條輕松學習Js之路。Js給人那種感覺的原因多半是因為它如下的特點:A:本身知識很抽象、...
摘要:個人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現在已經一年的時間了,由于工作比較忙,更新緩慢,后面還是會繼更新,現將已經寫好的文章整理一個目錄,方便更多的小伙伴去學習。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個人前端文章整理 從最開始萌生寫文章的想法,到著手...
閱讀 511·2021-10-09 09:44
閱讀 2073·2021-09-02 15:41
閱讀 3551·2019-08-30 15:53
閱讀 1829·2019-08-30 15:44
閱讀 1283·2019-08-30 13:10
閱讀 1188·2019-08-30 11:25
閱讀 1458·2019-08-30 10:51
閱讀 3365·2019-08-30 10:49