国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

js&jq面試筆記(下)

xinhaip / 3313人閱讀

摘要:面試筆記,該部分為下部分。構造函數模式使用自定義的構造函數與普通函數一樣,只是用它來創建對象,定義對象類型如的屬性和方法。使用原型來添加屬性共享一個原型對象的方法原型是指向原型對象的,這個原型對象與構造函數沒有太大關系,唯一的關系

js&jq面試筆記,該部分為下部分。

字符串相關 1、定義一個方法,用于將string中的每個字符之間加一個空格,并輸出
如:"hello" -> "h e l l o"

function joinSpace(str){
    return str.split("").join(" ")
}
2、JavaScript中如何檢測一個變量是一個String類型?請寫出函數實現
方法1
function isString(obj){
    return typeof(obj) === "string"? true: false;
    // returntypeof obj === "string"? true: false;
}

方法2
function isString(obj){
    return obj.constructor === String? true: false;
}

方法3
function isString(obj){
     return Object.prototype.toString.call(obj) === "[object String]"?true:false;
}
如:
var isstring = isString("xiaoming");
console.log(isstring);  // true
3、請用js去除字符串空格?
方法一:使用replace正則匹配的方法
    去除所有空格: 
    str = str.replace(/s*/g,"");      
    
    去除兩頭空格: 
    str = str.replace(/^s*|s*$/g,"");
    
    去除左空格: 
    str = str.replace( /^s*/, “”);
    
    去除右空格: 
    str = str.replace(/(s*$)/g, "");
    
    str為要去除空格的字符串,實例如下:
    var str = " 23 23 ";
    var str2 = str.replace(/s*/g,"");
    console.log(str2); // 2323

方法二:使用str.trim()方法
    str.trim() //局限性:無法去除中間的空格,實例如下:
    var str = "   xiao  ming   ";
    var str2 = str.trim();
    console.log(str2);   //xiao  ming 
    同理:
    str.trimLeft(),str.trimRight() //分別用于去除字符串左右空格。

方法三:使用jquery,$.trim(str)方法
    $.trim(str) 局限性:無法去除中間的空格,實例如下:
    var str = "   xiao  ming   ";
    var str2 = $.trim(str)
    console.log(str2);   //  xiao  ming
4、你如何獲取瀏覽器URL中查詢字符串中的參數?
//測試地址為:http://www.runoob.com/jquery/misc-trim.html?channelid=12333&name=xiaoming&age=23
function showWindowHref(){
    var sHref = window.location.href;
    var args = sHref.split("?");
    if(args[0] == sHref){
        return "";
    }
    var arr = args[1].split("&");
    var obj = {};
    for(var i = 0;i< arr.length;i++){
        var arg = arr[i].split("=");
        obj[arg[0]] = arg[1];
    }
    return obj;
}
var href = showWindowHref(); // obj
console.log(href["name"]); // xiaoming
5、js 字符串操作函數
//這里只是列舉了常用的字符串函數,具體使用方法,請參考網址。
concat()        將兩個或多個字符的文本組合起來,返回一個新的字符串。
indexOf()       返回字符串中一個子串第一處出現的索引。如果沒有匹配項,返回 -1 。
charAt()        返回指定位置的字符。
lastIndexOf()   返回字符串中一個子串最后一處出現的索引,如果沒有匹配項,返回 -1 。
match()         檢查一個字符串是否匹配一個正則表達式。
substr()        返回從string的startPos位置,長度為length的字符串
substring()     返回字符串的一個子串。傳入參數是起始位置和結束位置。
slice()         提取字符串的一部分,并返回一個新字符串。
replace()       用來查找匹配一個正則表達式的字符串,然后使用新字符串代替匹配的字符串。
search()        執行一個正則表達式匹配查找。如果查找成功,返回字符串中匹配的索引值。否則返回 -1 。
split()         通過將字符串劃分成子串,將一個字符串做成一個字符串數組。
length          返回字符串的長度,所謂字符串的長度是指其包含的字符的個數。
toLowerCase()   將整個字符串轉成小寫字母。
toUpperCase()   將整個字符串轉成大寫字母。
6、判斷一個字符串中出現次數最多的字符,統計這個次數
var str = "asdfssaaasasasasaa";
var json = {};
for (var i = 0; i < str.length; i++) {
    if(!json[str.charAt(i)]){   //判斷json中是否存在當前str.charAr(i)的值
       json[str.charAt(i)] = 1;   //如果不存在,則將其存放在json中,并且賦值為1,相當于出現的次數為1
    }else{
       json[str.charAt(i)]++;  //如果存在,則這個字符的值加1,相當于次數加1
    }
};
var iMax = 0;
var iIndex = "";
for(var i in json){
    if(json[i]>iMax){   //判斷當前json中的鍵值(相當于當前鍵所在字符的次數)是否大于iMax
         iMax = json[i];
         iIndex = i;
    }
}        
console.log("出現次數最多的是:"+iIndex+"出現"+iMax+"次");
數組(Array)對象 1、Array相關的屬性和方法

Array 對象屬性

constructor 返回對創建此對象的數組函數的引用。

var test=new Array();
if (test.constructor==Array){
    document.write("This is an Array");
}
    
length 設置或返回數組中元素的數目。

prototype 使您有能力向對象添加屬性和方法。

Array 對象方法

join() 把數組的所有元素放入一個字符串。元素通過指定的分隔符進行分隔。
    var arr = ["xiao","lin","qiqi","mingtian"];
    var arr2 = arr.join(",");
    console.log(arr2); // 根據","隔開返回的字符串為:"xiao,lin,qiqi,mingtian"
    
pop() 刪除并返回數組的最后一個元素。 
    var arr = [2,3,4,5];
    var arr2 = arr.pop();
    console.log(arr2); // 刪除的數組的最后一個元素為:5
    console.log(arr);  // 刪除元素之后的數組為:[2, 3, 4]
    
shift() 刪除并返回數組的第一個元素
    var arr = [2,3,4,5];
    var arr2 = arr.shift();
    console.log(arr2); // 刪除的數組的第一個元素為:2
    console.log(arr);  // 刪除元素之后的數組為:[3, 4,5]
    
push() 向數組的末尾添加一個或更多元素,并返回新的長度。
    var arr = [2,3,4,5];
    var arr2 = arr.push(6);
    console.log(arr2);  // 返回的數組長度:5 
    console.log(arr);  // [2, 3, 4, 5, 6]
    
unshift() 向數組的開頭添加一個或更多元素,并返回新的長度。
    var arr = ["xiao","ming","qiqi","aiming"];
    var arr1 = arr.unshift("lang");
    console.log(arr1);  // 返回的數組的長度:  5
    console.log(arr);  //向數組開頭添加元素返回的結果:["lang", "xiao", "ming", "qiqi", "aiming"]
    
reverse() 顛倒數組中元素的順序。
    var arr = [2,3,4,5];
    arr.reverse();
    console.log(arr);   //  [5, 4, 3, 2]
    
slice() 從某個已有的數組返回選定的元素
    var arr = [2,3,4,5];
    var arr2 = arr.slice(1,3);
    console.log(arr2);  // 截取區間返回的數組為:[3, 4]
    console.log(arr);  // [2, 3, 4, 5]
    
sort() 對數組的元素進行排序
    借助排序函數,實現數值由小到大排序
    function sortNumber(a,b){
        return a - b
    }
    var arr = [23,30,42,5];
    var arr2 = arr.sort(sortNumber);
    console.log(arr2);  // [5, 23, 30, 42]
    console.log(arr);   // [5, 23, 30, 42]

    借助排序函數,實現數值由大到小排序
    function sortNumber(a,b){
        return b - a
    }
    var arr = [23,30,42,5];
    var arr2 = arr.sort(sortNumber);
    console.log(arr2);  // [42, 30, 23, 5]
    console.log(arr);  // [42, 30, 23, 5]

splice() 刪除元素,并向數組添加新元素。
    語法:arrayObject.splice(index,howmany,item1,.....,itemX)
    index:必需。整數,規定添加/刪除項目的位置,使用負數可從數組結尾處規定位置。
    howmany:必需。要刪除的項目數量。如果設置為 0,則不會刪除項目。
    item1, ..., itemX:可選。向數組添加的新項目。

    // 創建一個新數組,并向其添加一個元素
    var arr = [1,2,3,4];
    arr.splice(2,0,5);
    console.log(arr);  // [1, 2, 5, 3, 4]

    // 刪除位于 index 2 的元素,并添加一個新元素來替代被刪除的元素:
    var arr = [1,2,3,4];
    arr.splice(2,1,5);
    console.log(arr);  // [1, 2, 5, 4]
    
toString() 把數組轉換為字符串,并返回結果。
    var arr = ["xiao","ming","qiqi","aiming"];
    arr.toString();
    console.log(arr);  // ["xiao", "ming", "qiqi", "aiming"]
2、編寫一個方法 去掉一個數組的重復元素
方法一
var arr = [0,2,3,4,4,0,2];
var obj = {};
var tmp = [];
for(var i = 0 ;i< arr.length;i++){
   if( !obj[arr[i]] ){
      obj[arr[i]] = 1;
      tmp.push(arr[i]);
   }
}
console.log(tmp);       //結果如下: [0, 2, 3, 4]

方法二
var arr = [2,3,4,4,5,2,3,6];
var arr2 = [];
for(var i = 0;i< arr.length;i++){
    if(arr2.indexOf(arr[i]) < 0){
        arr2.push(arr[i]);
    }
}
console.log(arr2);      //結果為:[2, 3, 4, 5, 6]

方法三
var arr = [2,3,4,4,5,2,3,6];
var arr2 = arr.filter(function(element,index,self){
    return self.indexOf(element) === index;
});
console.log(arr2);      //結果為:[2, 3, 4, 5, 6]

方法四:(ES6提供了新的數據結構 Set)
let unique= [...new Set(array)];
let unique= [...new Set([2,3,4,4,5,2,3,6])];
console.log(unique)
3、求數組的最值?
求數組最大值:Math.max.apply(null,arr);
var arr = [3,43,23,45,65,90];
var max = Math.max.apply(null,arr);
console.log(max);
// 90

求數組最小值:Math.min.apply(null,arr);
var arr = [3,43,23,45,65,90];
var min = Math.min.apply(null,arr);
console.log(min);
// 3
4、數組排序相關
選擇排序
/**
*以一個角標的元素和其他元素進行比較。
*在內循環第一次結束,最值出現的頭角標位置上。
*/
function selectSort(array) {
    if (Object.prototype.toString.call(array).slice(8, -1) === "Array") {
        var len = array.length, temp;
        for (var i = 0; i < len - 1; i++) {  //輪數
            var min = array[i];
            for (var j = i + 1; j < len; j++) {  //第一個與第二個比較
                if (array[j] < array[i]) {
                    temp = array[i];
                    array[i] = array[j];
                    array[j] = temp;
                }
            }
        }
        return array;
    } else {
        return "array is not an Array!";
    }
}

冒泡排序
/**
*比較方式:相鄰兩個元素進行比較,如果后一個比前一個小,換位置。
*原理:內循環結束一次,最值出現在尾角標位置。
*/
function bubbleSort(array) {
    if (Object.prototype.toString.call(array).slice(8, -1) === "Array") {
        var len = array.length, temp;
        for(var j=0;jarr[i+1]){
                    var temp = arr[i];
                    arr[i] = arr[i+1];
                    arr[i+1] = temp;
                }
            } 
        }
        return array;
    } else {
        return "array is not an Array!";
    }
}


二分插入排序
/**
*為了提高查找效率,可使用折半查找的方式,注意:這種查找只對有序的數組有效。這種方式也叫二分查找法。
*/
function binaryInsertionSort(array) {
    if (Object.prototype.toString.call(array).slice(8, -1) === "Array") {
        for (var i = 1; i < array.length; i++) {
            var key = array[i], left = 0, right = i - 1;
            while (left <= right) {
                var middle = parseInt((left + right) / 2);
                if (key < array[middle]) {
                    right = middle - 1;
                } else {
                    left = middle + 1;
                }
            }
            for (var j = i - 1; j >= left; j--) {
                array[j + 1] = array[j];
            }
            array[left] = key;
        }
        return array;
    } else {
        return "array is not an Array!";
    }
}
5、數組的翻轉(非reverse())
方法一:
var arr = [1,2,3,4];
var arr2 = [];
while(arr.length) {
    var num = arr.pop(); //刪除數組最后一個元素并返回被刪除的元素
    arr2.push(num);
}
console.log(arr2);
// [4, 3, 2, 1]

方法二:
var arr = [1,2,3,4];
var arr2 = [];
while(arr.length){
    var num = arr.shift(); //刪除數組第一個元素并返回被刪除的元素
    arr2.unshift(num);
}
console.log(arr2);
6、在Javascript中什么是偽數組?如何將偽數組轉化為標準數組?

偽數組(類數組):無法直接調用數組方法或期望length屬性有什么特殊的行為,但仍可以用真正數組遍歷方法來遍歷它們。

典型的是函數的argument參數,還有像調用getElementsByTagName,document.childNodes之類的,它們都返回NodeList對象都屬于偽數組。

a.使用Array.prototype.slice.call();        
    Array.prototype.slice.call({  
     0:"likeke",  
     1:12,  
     2:true,  
     length:3  
    });  
    //["likeke", 12, true]
    
b.使用[].slice.call(),了解js原型鏈的都知道,實際上這種方法和第一中方法是一樣的,但上面第一種方式相對效率更高。
    [].slice.call({  
     0:"likeke",  
     1:12,  
     2:true,  
     length:3  
    });  
    //["likeke", 12, true] 
    
c. 使用ES6中Array.from方法;
    Array.from({  
     0:"lk",  
     1:12,  
     2:2013,  
     3:"長安大學",  
     length:4  
    });  
    //["lk", 12, 2013, "長安大學"]
對象相關 1、獲取JavaScript對象鍵名
var obj = {name: "wan",age: 20, sex: "male"};  
var objKey = [];  
for(var item in obj){  
  if(obj.hasOwnProperty(item)){  
    objKey.push(item);  
  }  
}  
//for(var item in obj){  
//    objKey.push(item);  
//}  
console.log(objKey);//["name", "age", "sex"]
2、call和apply的區別

語法一:func.call(thisObj,a,b,c...) || func.apply(thisObj,array)
定義:將函數(方法) func 綁定到對象 thisObj 上去運行,改變了函數func 原有的 this 的指向,this指向了對象thisObj(js中的函數是對象,函數名是對 Function 對象的引用)

語法二:obj.call(thisObj,a,b,c...) || obj.apply(thisObj,array)
定義:將對象 obj 的屬性和方法添加到對象 thisObj 上,即 thisObj 繼承了 obj

區別:call的參數個數,從第二個開始 大于等于 0個,為單個變量;apply的參數只有兩個,第二個參數為一個數組,即array = [a,b,c...];

實例一:借調方法,對象sub借調對象add的方法add(函數也是對象)

    function add(a,b){return a+b}

    function sub(a,b){return a-b}

    add.call(sub,3,1)//4

    sub.call(add,3,1)//2

    add.call(sub,3,1) === add(3,1)

實例二:改變this指向

    function a(){console.log(this)}

    var obj = {}

    a()//window

    a.call()//window

    a.call(obj)//obj

實例三:實現繼承

    function Animal(name){this.name=name;this.showName=function(){alert(this.name)}}
    function Cat(name){

        Animal.call(this,name); //將Animal對象的屬性和方法應用到Cat上,因此Cat繼承了Animal的所有屬性和方法
    }
    var cat = new Cat(“Black Cat”);
    cat.showName(); //Black Cat

實例四:多重繼承


    function add(a,b){return a+b}

    function sub(a,b){return a-b}

    function calc(a,b){

        add.call(this)

        sub.call(this)

    }
3、js中改變this指向的方法
call、apply、bind,this總是指向調用它的對象
4、為下面的類增加一個方法method1
var A = function(){}
A.prototype.method1 = function(a,b){return a+b}
5、實現Parent類和Child類,并建立Parent和Child的繼承關系

面向對象的基本特征有:封閉、繼承、多態。

function Parent(){
    this.surname = "wan";
    this.work = function(){console.log("i like work")}
}
function Child(){}

原型鏈繼承:Child.prototype = new Parent()
    實例化:let person = new Child();
    console.log(person.surname);//wan
    person.work();//i like work

構造函數繼承:function Child(){Parent.call(this)}

組合繼承:
    function Child(){
        Parent.call(this);//繼承屬性
    }
    Child.prototype = new Parent();//繼承方法

原型式繼承:
    function object(obj){
      function Func(){};
      Func.prototype = obj;
      return new Func();
    }
    var Child = object(Parent);

寄生式繼承:

寄生組合式繼承:
6、解釋原型和原型鏈

原型:即原型對象,原型對象上定義方法和屬性的目的是為了被子類繼承和使用。原型鏈的形成真正是靠__proto__ 而非prototype

原型鏈:每個對象都有原型,對象的原型指向原型對象,即子對象的原型指向父對象,父對象的原型指向爺爺對象,這種原型層層連接起來的就構成了原型鏈。

7、定義一個類的私有屬性和公有屬性
function Person(){
    var sex = "man";//var 私有
    this.surnname = "wan";//this 公有
}
8、實現一個函數clone,可以對JavaScript中的5種主要的數據類型(包括Number、String、Object、Array、Boolean)進行值復制。
(Object.prototype.toString.call()方法及應用)
/**
 * 對象克隆
 * 支持基本數據類型及對象
 * 遞歸方法
 */
function clone(obj) {
    var o;
    switch (typeof obj) {
        case "undefined":
            break;
        case "string":
            o = obj + "";
            break;
        case "number":
            o = obj - 0;
            break;
        case "boolean":
            o = obj;
            break;
        case "object": // object 分為兩種情況 對象(Object)或數組(Array)
            if (obj === null) {
                o = null;
            } else {
                if (Object.prototype.toString.call(obj).slice(8, -1) === "Array") {
                    o = [];
                    for (var i = 0; i < obj.length; i++) {
                        o.push(clone(obj[i]));
                    }
                } else {
                    o = {};
                    for (var k in obj) {
                        o[k] = clone(obj[k]);
                    }
                }
            }
            break;
        default:
            o = obj;
            break;
    }
    return o;
}

//測試
var a=[12,34,"123"];
console.log(clone(a));
var b=null;
console.log(clone(b));
var c={1:"a",2:"b",3:"c"};
console.log(clone(c));
var d=1;
console.log(clone(d));
9、創建對象

使用Object構造函數或對象字面量都可以創建對象,但缺點是創建多個對象時,會產生大量的重復代碼,因此下面介紹可解決這個問題的創建對象的方法

1、工廠模式
    function createPerson(name, age, job) {
        var o = new Object();
        o.name = name;
        o.age = age;
        o.job = job;
        o.getName = function () {
            return this.name;
        }
        return o;//使用return返回生成的對象實例
    }
    var person = createPerson("Jack", 19, "SoftWare Engineer");
    創建對象交給一個工廠方法來實現,可以傳遞參數,但主要缺點是無法識別對象類型,因為創建對象都是使用Object的原生構造函數來完成的。

2、構造函數模式
    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.getName = function () {
            return this.name;
        }
    }
    var person1 = new Person("Jack", 19, "SoftWare Engineer");
    var person2 = new Person("Liye", 23, "Mechanical Engineer");
    使用自定義的構造函數(與普通函數一樣,只是用它來創建對象),定義對象類型(如:Person)的屬性和方法。它與工廠方法區別在于:

    沒有顯式地創建對象,直接將屬性和方法賦值給this對象;沒有return語句;
    此外,要創建Person的實例,必須使用new關鍵字,以Person函數為構造函數,傳遞參數完成對象創建;實際創建經過以下4個過程:

    創建一個對象
    將函數的作用域賦給新對象(因此this指向這個新對象,如:person1)
    執行構造函數的代碼
    返回該對象
    上述由Person構造函數生成的兩個對象person1與person2都是Person的實例,因此可以使用instanceof判斷,并且因為所有對象都繼承Object,因此person1 instanceof Object也返回真:

    alert(person1 instanceof Person);//true;
    alert(person2 instanceof Person);//true;
    alert(person1 instanceof Object);//true;
    alert(person1.constructor === person2.constructor);//ture;
    雖然構造函數方式比較不錯,但也存在缺點,那就是在創建對象時,特別針對對象的屬性指向函數時,會重復的創建函數實例,以上述代碼為基礎,可以改寫為:

    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.getName = new Function () {//改寫后效果與原代碼相同,不過是為了方便理解
            return this.name;
        }
    }
    上述代碼,創建多個實例時,會重復調用new Function();創建多個函數實例,這些函數實例還不是一個作用域中,當然這一般不會有錯,但這會造成內存浪費。
    當然,可以在函數中定義一個getName = getName的引用,而getName函數在Person外定義,這樣可以解決重復創建函數實例問題,但在效果上并沒有起到封裝的效果,如下所示:

    function Person(name,age,job){
        this.name = name;
        this.age = age;
        this.job = job;
        this.getName = getName;
    }
    function getName() {//到處是代碼,看著亂!!
        return this.name;
    }
    
    
3、原型模式
    JS每個函數都有一個prototype(原型)屬性,這個屬性是一個指針,指向一個對象,它是所有通過new操作符使用函數創建的實例的原型對象。
    原型對象最大特點是,所有對象實例共享它所包含的屬性和方法,也就是說,所有在原型對象中創建的屬性或方法都直接被所有對象實例共享。

    function Person(){}
    Person.prototype.name = "Jack";//使用原型來添加屬性
    Person.prototype.age = 29;
    Person.prototype.getName = function(){
        return this.name;
    }
    var person1 = new Person();
    alert(person1.getName());//Jack
    var person2 = new Person();
    alert(person1.getName === person2.getName);//true;共享一個原型對象的方法

    原型是指向原型對象的,這個原型對象與構造函數沒有太大關系,唯一的關系是函數的prototype是指向這個原型對象!而基于構造函數創建的對象實例也包含一個內部指針為:[[prototype]]指向原型對象。

實例屬性或方法的訪問過程是一次搜索過程:
    首先從對象實例本身開始,如果找到屬性就直接返回該屬性值;
    如果實例本身不存在要查找屬性,就繼續搜索指針指向的原型對象,在其中查找給定名字的屬性,如果有就返回;
    基于以上分析,原型模式創建的對象實例,其屬性是共享原型對象的;但也可以自己實例中再進行定義,在查找時,就不從原型對象獲取,而是根據搜索原則,得到本實例的返回;簡單來說,就是實例中屬性會屏蔽原型對象中的屬性;

原型與in操作符
    一句話:無論原型中屬性,還是對象實例的屬性,都可以使用in操作符訪問到;要想判斷是否是實例本身的屬性可以使用object.hasOwnProperty(‘attr’)來判斷;

原生對象中原型
    原生對象中原型與普通對象的原型一樣,可以添加/修改屬性或方法,如以下代碼為所有字符串對象添加去左右空白原型方法:
    
    String.prototype.trim = function(){
        return this.replace(/^s+/,"").replace(/s+$/,"");
    }
    var str = " word space ";
    alert("!"+str.trim()+"!");//!word space!
    
    原型模式的缺點,它省略了為構造函數傳遞初始化參數,這在一定程序帶來不便;另外,最主要是當對象的屬性是引用類型時,它的值是不變的,總是引用同一個外部對象,所有實例對該對象的操作都會其它實例:

    function Person() {    }
    Person.prototype.name = "Jack";
    Person.prototype.lessons = ["Math","Physics"];
    var person1 = new Person();
    person1.lessons.push("Biology");
    var person2 = new Person();
    alert(person2.lessons);//Math,Physics,Biology,person1修改影響了person2

    
4、組合構造函數及原型模式
    目前最為常用的定義類型方式,是組合構造函數模式與原型模式。構造函數模式用于定義實例的屬性,而原型模式用于定義方法和共享的屬性。結果,每個實例都會有自己的一份實例屬性的副本,但同時又共享著對方方法的引用,最大限度的節約內存。此外,組合模式還支持向構造函數傳遞參數,可謂是集兩家之所長。

    function Person(name, age, job) {
        this.name = name;
        this.age = age;
        this.job = job;
        this.lessons = ["Math", "Physics"];
    }
    Person.prototype = {
        constructor: Person,//原型字面量方式會將對象的constructor變為Object,此外強制指回Person
        getName: function () {
            return this.name;
        }
    }
    var person1 = new Person("Jack", 19, "SoftWare Engneer");
    person1.lessons.push("Biology");
    var person2 = new Person("Lily", 39, "Mechanical Engneer");
    alert(person1.lessons);//Math,Physics,Biology
    alert(person2.lessons);//Math,Physics
    alert(person1.getName === person2.getName);//true,//共享原型中定義方法

    在所接觸的JS庫中,jQuery類型的封裝就是使用組合模式來實例的!!!


5、動態原型模式
    組合模式中實例屬性與共享方法(由原型定義)是分離的,這與純面向對象語言不太一致;動態原型模式將所有構造信息都封裝在構造函數中,又保持了組合的優點。

    其原理就是通過判斷構造函數的原型中是否已經定義了共享的方法或屬性,如果沒有則定義,否則不再執行定義過程。該方式只原型上方法或屬性只定義一次,且將所有構造過程都封裝在構造函數中,對原型所做的修改能立即體現所有實例中:

    function Person(name, age, job) {
        this.name = name;
        this.age = age;
        this.job = job;
        this.lessons = ["Math", "Physics"];
    }
    if (typeof this.getName != "function") {//通過判斷實例封裝
      Person.prototype = {
        constructor: Person,//原型字面量方式會將對象的constructor變為Object,此外強制指回Person
        getName: function () {
          return this.name;
        }
      }
    }
    var person1 = new Person("Jack", 19, "SoftWare Engneer");
    person1.lessons.push("Biology");
    var person2 = new Person("Lily", 39, "Mechanical Engneer");
    alert(person1.lessons);//Math,Physics,Biology
    alert(person2.lessons);//Math,Physics
    alert(person1.getName === person2.getName);//true,//共享原型中定義方法
jQuery相關 1、jQuery為DOM元素綁定點擊事件的方法和區別
    .click(function(){}) 

    .bind({"click mouseleave",function(){}},{"click mouseleave",function(){}}) //在.bind()綁定事件的時候,這些元素必須已經存在。

    .on() //為動態綁定事件

    .one("click", function() {alert("This will be displayed only once.");});//綁定一個事件,并且只運行一次,然后刪除自己,
2、jQuery 庫中的 $() 是什么?

  $() 函數是 jQuery() 函數的別稱。$() 函數用于將任何對象包裹成 jQuery 對象,接著你就被允許調用定義在 jQuery 對象上的多個不同方法。

可以將一個選擇器字符串傳入` $()` 函數,它會返回一個包含所有匹配的 DOM 元素數組的 jQuery 對象。
3、如何找到所有 HTML select 標簽的選中項?
$("[name=selectname] :selected")
4、$(this)this 關鍵字在 jQuery 中有何不同?

$(this) 返回一個 jQuery 對象,你可以對它調用多個 jQuery 方法,比如用 text() 獲取文本,用val() 獲取值等等。

而 this 代表當前元素,它是 JavaScript 關鍵詞中的一個,表示上下文中的當前 DOM 元素。你不能對它調用 jQuery 方法,直到它被 $() 函數包裹,例如 $(this)。

5、jquery怎么移除標簽onclick屬性?
獲得a標簽的onclick屬性: $("a").attr("onclick")

刪除onclick屬性:$("a").removeAttr("onclick");

設置onclick屬性:$("a").attr("onclick","test();");
6、jquery中addClass,removeClass,toggleClass的使用。
$(selector).addClass(class):為每個匹配的元素添加指定的類名

$(selector).removeClass(class):從所有匹配的元素中刪除全部或者指定的類,刪除class中某個值;

$(selector).toggleClass(class):如果存在(不存在)就刪除(添加)一個類

$(selector).removeAttr(class);刪除class這個屬性;
7、JQuery有幾種選擇器?
(1)、基本選擇器:#id,class,element,*;

(2)、層次選擇器:parent > child,prev + next ,prev ~ siblings

(3)、基本過濾器選擇器::first,:last ,:not ,:even ,:odd ,:eq ,:gt ,:lt

(4)、內容過濾器選擇器: :contains ,:empty ,:has ,:parent

(5)、可見性過濾器選擇器::hidden ,:visible

(6)、屬性過濾器選擇器:[attribute] ,[attribute=value] ,[attribute!=value] ,[attribute^=value] ,[attribute$=value] ,[attribute*=value]

(7)、子元素過濾器選擇器::nth-child ,:first-child ,:last-child ,:only-child

(8)、表單選擇器: :input ,:text ,:password ,:radio ,:checkbox ,:submit 等;

(9)、表單過濾器選擇器::enabled ,:disabled ,:checked ,:selected
8、jQuery中的Delegate()函數有什么作用?

delegate()會在以下兩個情況下使用到:

1、如果你有一個父元素,需要給其下的子元素添加事件,這時你可以使用delegate()了,代碼如下:

`$("ul").delegate("li", "click", function(){ $(this).hide(); });`

2、當元素在當前頁面中不可用時,可以使用delegate()

9、$(document).ready()方法和window.onload有什么區別?
(1)、window.onload 方法是在網頁中所有的元素(包括元素的所有關聯文件)完全加載到瀏覽器后才執行的。

(2)、$(document).ready() 方法可以在DOM載入就緒時就對其進行操縱,并調用執行綁定的函數。
10、如何用jQuery禁用瀏覽器的前進后退按鈕?
  $(document).ready(function() {
    window.history.forward(1);
    //OR window.history.forward(-1);
  });
11、 jquery中$.get()提交和$.post()提交有區別嗎?

相同點:都是異步請求的方式來獲取服務端的數據;

異同點:

1、請求方式不同:$.get() 方法使用GET方法來進行異步請求的。$.post() 方法使用POST方法來進行異步請求的。

2、參數傳遞方式不同:get請求會將參數跟在URL后進行傳遞,而POST請求則是作為HTTP消息的實體內容發送給Web服務器的,這種傳遞是對用戶不可見的。

3、數據傳輸大小不同:get方式傳輸的數據大小不能超過2KB 而POST要大的多

4、安全問題: GET 方式請求的數據會被瀏覽器緩存起來,因此有安全問題。

12、寫出一個簡單的$.ajax()的請求方式?
$.ajax({
    url:"http://www.baidu.com",
    type:"POST",
    data:data,
    cache:true,
    headers:{},
    beforeSend:function(){},
    success:function(){},
    error:function(){},
    complete:function(){}
}); 
13、jQuery的事件委托方法bind 、live、delegate、on之間有什么區別?

(1)、bind 【jQuery 1.3之前】

定義和用法:主要用于給選擇到的元素上綁定特定事件類型的監聽函數;

語法:bind(type,[data],function(eventObject));

特點:

  (1)、適用于頁面元素靜態綁定。只能給調用它的時候已經存在的元素綁定事件,不能給未來新增的元素綁定事件。

  (2)、當頁面加載完的時候,你才可以進行bind(),所以可能產生效率問題。

實例如下:$( "#members li a" ).bind( "click", function( e ) {} );

(2)、live 【jQuery 1.3之后】

定義和用法:主要用于給選擇到的元素上綁定特定事件類型的監聽函數;

語法:live(type, [data], fn);

特點:

  (1)、live方法并沒有將監聽器綁定到自己(this)身上,而是綁定到了this.context上了。

  (2)、live正是利用了事件委托機制來完成事件的監聽處理,把節點的處理委托給了document,新添加的元素不必再綁定一次監聽器。

  (3)、使用live()方法但卻只能放在直接選擇的元素后面,不能在層級比較深,連綴的DOM遍歷方法后面使用,即$(“ul”").live...可以,但$("body").find("ul").live...不行; 

實例如下:$( document ).live( "click", "#members li a", function( e ) {} );

(3)、delegate 【jQuery 1.4.2中引入】

定義和用法:將監聽事件綁定在就近的父級元素上

語法:delegate(selector,type,[data],fn)

特點:

  (1)、選擇就近的父級元素,因為事件可以更快的冒泡上去,能夠在第一時間進行處理。

  (2)、更精確的小范圍使用事件代理,性能優于.live()。可以用在動態添加的元素上。

實例如下:

$("#info_table").delegate("td","click",function(){/*顯示更多信息*/});

$("table").find("#info").delegate("td","click",function(){/*顯示更多信息*/});

(4)、on 【1.7版本整合了之前的三種方式的新事件綁定機制】

定義和用法:將監聽事件綁定到指定元素上。

語法:on(type,[selector],[data],fn)

實例如下:$("#info_table").on("click","td",function(){/*顯示更多信息*/});參數的位置寫法與delegate不一樣。

說明:on方法是當前JQuery推薦使用的事件綁定方法,附加只運行一次就刪除函數的方法是one()。

總結:.bind(), .live(), .delegate(),.on()分別對應的相反事件為:.unbind(),.die(), .undelegate(),.off()

開發及性能優化 1、規避javascript多人開發函數重名問題
命名空間
封閉空間
js模塊化mvc(數據層、表現層、控制層)
seajs
變量轉換成對象的屬性
對象化
2、請說出三種減低頁面加載時間的方法
壓縮css、js文件
合并js、css文件,減少http請求
外部js、css文件放在最底下
減少dom操作,盡可能用變量替代不必要的dom操作
3、你所了解到的Web攻擊技術

(1)XSS(Cross-Site Scripting,跨站腳本攻擊):指通過存在安全漏洞的Web網站注冊用戶的瀏覽器內運行非法的HTML標簽或者JavaScript進行的一種攻擊。

(2)SQL注入攻擊

(3)CSRF(Cross-Site Request Forgeries,跨站點請求偽造):指攻擊者通過設置好的陷阱,強制對已完成的認證用戶進行非預期的個人信息或設定信息等某些狀態更新。

4、web前端開發,如何提高頁面性能優化?

內容方面:

1.減少 HTTP 請求 (Make Fewer HTTP Requests)

2.減少 DOM 元素數量 (Reduce the Number of DOM Elements)

3.使得 Ajax 可緩存 (Make Ajax Cacheable)

針對CSS:

1.把 CSS 放到代碼頁上端 (Put Stylesheets at the Top)

2.從頁面中剝離 JavaScript 與 CSS (Make JavaScript and CSS External)

3.精簡 JavaScript 與 CSS (Minify JavaScript and CSS)

4.避免 CSS 表達式 (Avoid CSS Expressions)

針對JavaScript :

1. 腳本放到 HTML 代碼頁底部 (Put Scripts at the Bottom)

2. 從頁面中剝離 JavaScript 與 CSS (Make JavaScript and CSS External)

3. 精簡 JavaScript 與 CSS (Minify JavaScript and CSS)

4. 移除重復腳本 (Remove Duplicate Scripts)

面向圖片(Image):

1.優化圖片

2 不要在 HTML 中使用縮放圖片

3 使用恰當的圖片格式

4 使用 CSS Sprites 技巧對圖片優化

5、前端開發中,如何優化圖像?圖像格式的區別?

優化圖像:

1、不用圖片,盡量用css3代替。 比如說要實現修飾效果,如半透明、邊框、圓角、陰影、漸變等,在當前主流瀏覽器中都可以用CSS達成。

2、 使用矢量圖SVG替代位圖。對于絕大多數圖案、圖標等,矢量圖更小,且可縮放而無需生成多套圖。現在主流瀏覽器都支持SVG了,所以可放心使用!

3.、使用恰當的圖片格式。我們常見的圖片格式有JPEG、GIF、PNG。

基本上,內容圖片多為照片之類的,適用于JPEG。

而修飾圖片通常更適合用無損壓縮的PNG。

GIF基本上除了GIF動畫外不要使用。且動畫的話,也更建議用video元素和視頻格式,或用SVG動畫取代。

4、按照HTTP協議設置合理的緩存。

5、使用字體圖標webfont、CSS Sprites等。

6、用CSS或JavaScript實現預加載。

7、WebP圖片格式能給前端帶來的優化。WebP支持無損、有損壓縮,動態、靜態圖片,壓縮比率優于GIF、JPEG、JPEG2000、PG等格式,非常適合用于網絡等圖片傳輸。

圖像格式的區別:

 
矢量圖:圖標字體,如 font-awesome;svg 

位圖:gif,jpg(jpeg),png

區別:

1 、gif:是是一種無損,8位圖片格式。具有支持動畫,索引透明,壓縮等特性。適用于做色彩簡單(色調少)的圖片,如logo,各種小圖標icons等。

2、JPEG格式是一種大小與質量相平衡的壓縮圖片格式。適用于允許輕微失真的色彩豐富的照片,不適合做色彩簡單(色調少)的圖片,如logo,各種小圖標icons等。

3、png:PNG可以細分為三種格式:PNG8,PNG24,PNG32。后面的數字代表這種PNG格式最多可以索引和存儲的顏色值。

關于透明:PNG8支持索引透明和alpha透明;PNG24不支持透明;而PNG32在24位的PNG基礎上增加了8位(256階)的alpha通道透明;

優缺點:

1、能在保證最不失真的情況下盡可能壓縮圖像文件的大小。

2、對于需要高保真的較復雜的圖像,PNG雖然能無損壓縮,但圖片文件較大,不適合應用在Web頁面上。 


ES5和ES6 1、ES5和ES6的類
ES5的類
function Person(name) {
    this.name = name; 
}

Person.prototype.sayHello = function(){
    return "Hi, I am " + this.name;
}

ES6的類
class Person {
    constructor(name){
        this.name = name;
    }
    sayHello(){
        return "Hi, I am " + this.name;
    } 
}

typeof Person; //"function"

調用的方式都是一致的:
var me = new Person("Yecao");
2、ES5的繼承和ES6的繼承有什么區別?

ES5的繼承時通過prototype或構造函數機制來實現。ES5的繼承實質上是先創建子類的實例對象,然后再將父類的方法添加到this上(Parent.apply(this))。

ES6的繼承機制完全不同,實質上是先創建父類的實例對象this(所以必須先調用父類的super()方法),然后再用子類的構造函數修改this。

ES6繼承
class Father{
    constructor(name){
        this.name = name;
    }
    getName(){
        console.log(this.name);
    }
    //  這里是父類的f方法
    f(){
        console.log("fffffffffffffffffffffff");
    }
}

class Son extends Father{
    constructor(name,age){
        super(name); // HACK: 這里super()要在第一行
        this.age = age;
    }
    getAge(){
        console.log(this.age);
    }
    //  子類的f方法
    f(){
        console.log("sssssssssssssssssssssss");
    }
}
var s1 = new Son("張一",12);
s1.getName();
s1.getAge();
console.log(s1.__proto__);          //  為Son,不用修正
s1.f();                             //  打印ssssssssssssss
s1.__proto__ = new Father();        //  改變s1的原型指向,改為Father
s1.f();                             // 打印ffffffffffffff
console.log(s1.__proto__);          // 為Father

ES5繼承
function Father(name){
  this.name = name;
}
function Son(name,age){
  Father.call(this,name);
  this.age = age;
}
Father.prototype.getName = function(){
  console.log(this.name);
}
// 這里注意原型繼承要在,實例化s1變量之前,如果要使用原型鏈上的方法的話,子類的原型是父類的一個實例
Son.prototype = new Father;

// 修正構造器,這里注意要將Son的構造器指向賦值為Son,否則,打印出來的s1是Father對象
Son.prototype.constructor = Son;
Son.prototype.getAge = function(){
  console.log(this.age);
}
var s1 = new Son("李四",22);
console.log(s1);                            // Son {name:"李四",age:22}
s1.getName();                               // 李四
console.log(Son.prototype.constructor);     // Son
console.log(s1.constructor);                // Son,如果不糾正,則為Father
s1.getAge();                                // 22

//HACK:這里通過__proto__這個s1實例的屬性找到了Son的prototype,并為其添加了say的方法
s1.__proto__.say = function(){  
  console.log("hhhhhhhhhhhhhhhhhhhhhhhh");
}
s1.say()                                    // 打印 hhhhhhhhhhhhhhh

// NOTE: __proto__這個屬性是具體到某個實例化后的對象才有的屬性,指向他所屬的類的原型
console.log(new Son().__proto__);           // 為Son對象
2、ES6 Set和Map

Map和Set都叫做集合,但是他們也有所不同。Set常被用來檢查對象中是否存在某個鍵名,Map集合常被用來獲取已存的信息。

1、set類似于數組,但是成員的值都是唯一的,沒有重復的值。
Set 實例的方法分為兩大類:操作方法(用于操作數據)和遍歷方法(用于遍歷成員)。

 四個操作方法。
 add(value):添加某個值,返回Set結構本身。
 delete(value):刪除某個值,返回一個布爾值,表示刪除是否成功。
 has(value):返回一個布爾值,表示該值是否為Set的成員。
 clear():清除所有成員,沒有返回值。


Set 結構的實例有四個遍歷方法,可以用于遍歷成員。
keys():返回鍵名的遍歷器
values():返回鍵值的遍歷器
entries():返回鍵值對的遍歷器
forEach():使用回調函數遍歷每個成員

2、Set類似于數組,而Map就類似于鍵值對(Key, Value);

它類似于對象,也是鍵值對的集合,但是“鍵”的范圍不限于字符串,各種類型的值(包括對象)都可以當作鍵。
Map有size()屬性,查看Map對象大小,set(key , value) , get(Key), delete(key) , has(key) ,clear()方法。

 Map 結構原生提供三個遍歷器生成函數和一個遍歷方法。
 keys():返回鍵名的遍歷器。
 values():返回鍵值的遍歷器。
 entries():返回所有成員的遍歷器。
 forEach():遍歷 Map 的所有成員。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/96584.html

相關文章

  • js&amp;jq面試筆記(上)

    摘要:確定離開和操作的用法實例操作符判斷基本數據類型檢測對象的繼承關系,左操作數是對象,右操作數是構造函數可以準確判斷左對象是右對象的實例頁面的三種彈窗警告框確認框提示框請指出和的區別共同點這兩種事件都代表的是頁面文檔加載時觸發。 js&jq涉及內容眾多,分為上下兩部分進行整理,該部分為上部分。 1、對前端工程師這個職位你是怎么樣理解的? 前端是最貼近用戶的程序員,前端的能力就是能讓產品...

    SoapEye 評論0 收藏0
  • 回顧自己三次失敗的面試經歷

    摘要:站在這個時間點上,我對自己之前三次失敗的面試經歷做了一次深度回顧。關于我第三次面試失敗的經歷,依然是與輪播圖有關。當然,這次思特奇面試之旅,最后也是以失敗告終,這也是我離進大廠最近的一次。 showImg(https://segmentfault.com/img/bVYQuP?w=528&h=513); 前言 時間的齒輪已經來到了2017年的11月份,距離2018年僅僅還剩下不到兩...

    DC_er 評論0 收藏0
  • 回顧自己三次失敗的面試經歷

    摘要:站在這個時間點上,我對自己之前三次失敗的面試經歷做了一次深度回顧。關于我第三次面試失敗的經歷,依然是與輪播圖有關。當然,這次思特奇面試之旅,最后也是以失敗告終,這也是我離進大廠最近的一次。 showImg(https://segmentfault.com/img/bVYQuP?w=528&h=513); 前言 時間的齒輪已經來到了2017年的11月份,距離2018年僅僅還剩下不到兩...

    spacewander 評論0 收藏0
  • Deep in JS - 收藏集 - 掘金

    摘要:今天同學去面試,做了兩道面試題全部做錯了,發過來給道典型的面試題前端掘金在界中,開發人員的需求量一直居高不下。 排序算法 -- JavaScript 標準參考教程(alpha) - 前端 - 掘金來自《JavaScript 標準參考教程(alpha)》,by 阮一峰 目錄 冒泡排序 簡介 算法實現 選擇排序 簡介 算法實現 ... 圖例詳解那道 setTimeout 與循環閉包的經典面...

    enali 評論0 收藏0

發表評論

0條評論

xinhaip

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<