JavaScript基礎(一)

Javascipt的本地對象,內置對象和宿主對象javascript

本地對象:Object、Function、Array、String、Boolean、Number、Date、RegExp、Error、EvalError、RangeError、ReferenceError、SyntaxError、TypeError、URIError, 簡單來講,本地對象就是 ECMA一262 定義的類.html

內置對象:ECMA一262 把內置對象(built一in object)定義爲「由 ECMAScript 實現提供的、獨立於宿主環境的全部對象,在 ECMAScript 程序開始執行時出現」。這意味着開發者沒必要明確實例化內置對象,它已被實例化了。前端

一樣是「獨立於宿主環境」。根據定義咱們彷佛很難分清「內置對象」與「本地對象」的區別。而ECMA一262 只定義了兩個內置對象,即 Global 和 Math (它們也是本地對象,根據定義,每一個內置對象都是本地對象)。java

如此就能夠理解了。內置對象是本地對象的一種。而其包含的兩種對象中,Math對象咱們常常用到,可這個Global對象是啥東西呢?node

Global對象是ECMAScript中最特別的對象,由於實際上它根本不存在,有點玩人的意思。你們要清楚,在ECMAScript中,不存在獨立的函數,全部函數都必須是某個對象的方法。jquery

相似於isNaN()、parseInt()和parseFloat()方法等,看起來都是函數,而實際上,它們都是Global對象的方法。並且Global對象的方法還不止這些.es6

宿主對象: ECMAScript中的「宿主」就是咱們網頁的運行環境,即「操做系統」和「瀏覽器」。全部非本地對象都是宿主對象(host object),即由 ECMAScript 實現的宿主環境提供的對象。全部的BOM和DOM對象都是宿主對象。由於其對於不一樣的「宿主」環境所展現的內容不一樣。其實說白了就是,ECMAScript官方未定義的對象都屬於宿主對象,由於其未定義的對象大多數是本身經過ECMAScript程序建立的對象。自定義的對象也是宿主對象。面試

 說幾條javasprit的基本規範正則表達式

1.不要在同一行聲明多個變量。編程

2.請使用 ===/!==來比較true/false或者數值

3.使用對象字面量替代new Array這種形式

4.不要使用全局函數。

5.Switch語句必須帶有default分支

6.函數不該該有時候有返回值,有時候沒有返回值。

7.For循環必須使用大括號

8.If語句必須使用大括號

9.for一in循環中的變量 應該使用var關鍵字明確限定做用域,從而避免做用域污染。

 用js代碼簡單的介紹下本身

 function Person(name,jingli,jineng) {
      this.name=name;
      this.jingli=jingli;
      this.jineng=jineng;
    }
    Person.prototype.show=function(){
      console.log("我是"+this.name+";我有以下經歷:"+this.jingli+";我會以下技能:"+this.jineng);
    }
    var myself=new Person("小田","小田工做室創辦人,鳳翔網絡推廣顧問","熟悉前端基本技能,熟悉網絡營銷思想有實戰經驗,掌握項目經理技能,能夠編寫文檔,也可使用axure進行原型設計,掌握自動化測試和性能測試技能")
    myself.show();
View Code

  什麼是閉包(closure)爲何要用它

閉包是指有權訪問另外一個函數做用域中變量的函數,建立閉包的最多見的方式就是在一個函數內建立另外一個函數,經過另外一個函數訪問這個函數的局部變量,利用閉包能夠突破做用鏈域,將函數內部的變量和方法傳遞到外部。

閉包的特性:

1.函數內再嵌套函數

2.內部函數能夠引用外層的參數和變量

3.參數和變量不會被垃圾回收機制回收

例如://li節點的onclick事件都能正確的彈出當前被點擊的li索引

<ul id="testUL">

    <li> index = 0</li>

    <li> index = 1</li>

    <li> index = 2</li>

    <li> index = 3</li>

</ul>

<script type="text/javascript">

    var nodes = document.getElementsByTagName("li");

    for(i = 0;i<nodes.length;i+= 1){

        nodes[i].onclick = (function(i){

                  return function() {

                     console.log(i);

                  } //不用閉包的話,值每次都是4

                })(i);

    }

</script>

 
View Code

執行say667()後,say667()閉包內部變量會存在,而閉包內部函數的內部變量不會存在

使得Javascript的垃圾回收機制GC不會收回say667()所佔用的資源

由於say667()的內部函數的執行須要依賴say667()中的變量

這是對閉包做用的很是直白的描述

function say667() {

    // Local variable that ends up within closure

    var num = 666;

    var sayAlert = function() {

        alert(num);

    }

    num++;

    return sayAlert;

}

 var sayAlert = say667();

 sayAlert()//執行結果應該彈出的667
View Code

隨着瀏覽器的升級,大部分瀏覽器對於閉包引發的循環引用問題都可以順利解決。但IE9以前使用非本地JavaScript對象實現DOM對象,對於Javascript對象跟DOM對象使用不一樣的垃圾收集器。因此閉包在IE的這些版本中發生循環引用時便會致使內存泄露。

參考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

你知道哪些針對jQuery的優化方法

基於Class的選擇性的性能相對於Id選擇器開銷很大,由於需遍歷全部DOM元素。

頻繁操做的DOM,先緩存起來再操做。用Jquery的鏈式調用更好。

   好比:var str=$("a").attr("href");

    for (var i = size; i < arr.length; i++) {}

   for 循環每一次循環都查找了數組 (arr) 的.length 屬性,在開始循環的時候設置一個變量來存儲這個數字,可讓循環跑得更快:

   for (var i = size, length = arr.length; i < length; i++) {}

  用原型鏈繼承的方式寫一個類和子類

function Person(name,age){
        this.name=name;
        this.age=age;
    }
    Person.prototype.study=function(){
        return "學習"
    }
    /*var p1 =new Person("張三",20);*/
    /*p1.study();*/
    function Student(class_,name,age){
        this.class_=class_;
        this.name=name;
        this.age=age;
    }
    Student.prototype=new Person();
    var s1 =new Student("二班","李大人",16);
    console.log(s1.name,s1.age,s1.class_,s1.study());
View Code

 編寫一個方法求一個字符串的字節長度,假設:一個英文字符佔用一個字節,一箇中文字符佔用兩個字節

function num(str) {
    var num1 = str.length;
    var num2 = 0;
    for (var i = 0; i < str.length; i++) {
        if (str.charCodeAt(i) >= 10000) {
            num2++;
        }
    }
    console.log(num1 + num2)
}

 簡單歸納瀏覽器事件模型,如何得到資源dom節點

在各類瀏覽器中存在三種事件模型:原始事件模型( original event model),DOM2事件模型,IE事件模型.其中原始的事件模型被全部瀏覽器所支持,而DOM2中所定義的事件模型目前被除了IE之外的全部主流瀏覽器支持。

瀏覽器事件模型分爲三個階段

  一、捕獲階段

  二、目標階段

  三、冒泡階段

Dom節點獲取方法:

1.經過id屬性獲取 document.getElementById()

2.經過name屬性獲取 document.getElementsByName()

3.經過標籤名獲取 document.getElementsByTagName()

4.經過class屬性獲取 document.getElementsByClassName()

5.原生js中的querySelector 和 querySelectorAll方法也一樣能夠獲取到相應的dom節點,類似於jquery,但比jq更快

  判斷字符串是不是這樣組成的,第一個必須是字母,後面能夠是字母和數字、下劃線,總長度爲5一20(請使用正則表達式)

function if_fit(str){
        var reg=/^[A一Za一z]{1}\w{5,20}/g;
            var result=str.search(reg);
        return result;
    }

  截取字符串abcdefg的efg

var str="abcdefg";

console.log(str.slice(4));

 將字符串helloChina反轉輸出

var str = "helloChina";
    方法1:console.log( str.split("").reverse().join("") );'); 
    方法2:for (var x = str.length一1; x >=0; x一一) { 
    document.write(str.charAt(x)); 
}
    方法3:var a=str.split("");
 var rs = new Array;
while(a.length){
     rs.push(a.pop());
}
alert(rs.join(""));

簡述ECMASCRIPT6的新特性

1.增長塊做用域

2.增長let const

3.解構賦值

4.函數參數擴展 (函數參數可使用默認值、不定參數以及拓展參數)

5.增長class類的支持

6.增長箭頭函數

7.增長模塊和模塊加載(ES6中開始支持原生模塊化啦)

8.math, number, string, array, object增長新的API

  在javascript中什麼是僞數組,如何將僞數組轉化爲標準數組

這裏把符合如下條件的對象稱爲僞數組:

1,具備length屬性

2,按索引方式存儲數據

3,不具備數組的push,pop等方法

僞數組(類數組):沒法直接調用數組方法或指望length屬性有什麼特殊的行爲,不具備數組的push,pop等方法,但仍能夠對真正數組遍歷方法來遍歷它們。典型的是函數的argument參數,還有像調用document.getElementsByTagName, document.childNodes之類的,它們返回的NodeList對象都屬於僞數組。

可使用如下函數將僞數組轉化爲真正的Array對象(兼容問題處理)。

function  makeArray(c) {
    try{
        return Array.prototype.slice.call(c);
    }catch(e){
        var ret = [],i, len = c.length;
        for(i = 0; i < len; i++) {
            ret[i] = (c[i]);
        }
        return ret;
    }
}

  此外還有,ES6中數組的新方法 from()

function test(){
    var arg = Array.from(arguments);
    arg.push(5);
    console.log(arg);//1,2,3,4,5

}
test(1,2,3,4);

es6中,展開操做符對於實現了 Iterator 接口的對象轉爲真正的數組

任何 Iterator 接口的對象,均可以用擴展運算符轉爲真正的數組。

let nodeList = document.querySelectorAll('div');
let array = [...nodeList];

上面代碼中,querySelectorAll方法返回的是一個nodeList對象。它不是數組,而是一個相似數組的對象。這時,擴展運算符能夠將其轉爲真正的數組,緣由就在於NodeList對象實現了 Iterator 。

對於那些沒有部署 Iterator 接口的相似數組的對象,擴展運算符就沒法將其轉爲真正的數組。

let arrayLike = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3
};

// TypeError: Cannot spread non-iterable object.
let arr = [...arrayLike];

上面代碼中,arrayLike是一個相似數組的對象,可是沒有部署 Iterator 接口,擴展運算符就會報錯。這時,能夠改成使用Array.from方法將arrayLike轉爲真正的數組。

jquery中的,jQuery.toArray()方法

alert($('li').toArray());

jquery中,jQuery.makeArray(obj)

將類數組對象轉換爲數組對象。

類數組對象有 length 屬性,其成員索引爲 0 至 length - 1。實際中此函數在 jQuery 中將自動使用而無需特地轉換。

var arr = jQuery.makeArray(document.getElementsByTagName("div"));

如何實現瀏覽器內多個標籤頁之間的通訊?

經過WebSocket或SharedWorker把客戶端和服務器端創建socket鏈接,從而實現通訊;也能夠調用localstorge、cookies等本地存儲方法。

假設如今頁面裏有一個id是con的div,如今須要編寫js代碼,在頁面加載完成後 將div的高度設置成100px,寬度設置成60px,並設置成灰色的1px的邊框,背景設置成淺黃色。

window.onload=function(){
  var oDiv=document.getElementById("con");
  oDiv.style.height="100px";
  oDiv.style.width="60px";
  oDiv.style.width="1px solid gray";
  oDiv.style.backgroundColor="yellow";
}

 

對string對象進行擴展,使其具備刪除先後空格的方法

String.prototype.trim = function() {
  return    this.replace(/(^\s*)|(\s*$)/g, "");
}

 描述下你對js閉包。面向對象、繼承的理解

1)閉包理解:

  我的理解:閉包就是可以讀取其餘函數內部變量的函數;

使用閉包主要是爲了設計私有的方法和變量。閉包的優勢是能夠避免全局變量的污染,缺點是閉包會常駐內存,會增大內存使用量,使用不當很容易形成內存泄露。在js中,函數即閉包,只有函數纔會產生做用域的概念

閉包有三個特性:

1.函數嵌套函數

2.函數內部能夠引用外部的參數和變量

3.參數和變量不會被垃圾回收機制回收

閉包常見用途:

建立特權方法用於訪問控制

事件處理程序及回調

2) 面向對象:

  面向對象編程,即OOP,是一種編程範式,知足面向對象編程的語言,通常會提供類、封裝、繼承等語法和概念來輔助咱們進行面向對象編程。

 參考:

http://www.ruanyifeng.com/blog/2010/05/object一oriented_javascript_encapsulation.html

3)繼承:

對象繼承分兩種狀況,一種是構造函數的繼承,一種是原型(prototype)的繼承:

1.        構造函數的繼承,比較簡單,只須要在子對象中添加代碼:parent.apply(this, arguments);

關於原型的繼承最優化的方法,利用空對象做爲中介

2.        拷貝繼承

可參考:

http://www.javashuo.com/article/p-ueosnihj-ew.html

http://blog.csdn.net/james521314/article/details/8645815

javascript 進制轉換(2進制、8進制、10進制、16進制之間的轉換)? 

//十進制轉其餘  
var x=110;  
alert(x);  
alert(x.toString(8));  
alert(x.toString(32));  
alert(x.toString(16));  
//其餘轉十進制  
var x='110';  
alert(parseInt(x,2));  
alert(parseInt(x,8));  
alert(parseInt(x,16));  
//其餘轉其餘  
//先用parseInt轉成十進制再用toString轉到目標進制  
alert(String.fromCharCode(parseInt(141,8)))  
alert(parseInt('ff',16).toString(2));   

 setInterval 與 setTimeout ?

JavaScript是單線程的語言,但使用setTimout(延時器) 和 setInterval(定時器)能夠模擬多線程

setInterval(function(){
  console.log(111)
},1000)
setTimeout(function(){
  console.log(222)
},1000)

在JavaScript代碼執行期間,遇到setTimeout 和 setInterval 會將其依次放置到執行棧中,當其餘代碼執行完後纔開始執行執行棧中的「任務」,所以當碰到

... ...
setTimeout(function(){}, 0)
... ...

至關於將其中的任務放置到JavaScript代碼最後執行,但有一點要注意的是間隔的時間最小爲10ms,但通常狀況下這不是最小值,由於計算機的執行頻率通常爲60/s,因此最小值爲1000/60 = 16.66666...。此外還有使用setInterval時其中的「任務」也是一個費時的過程則表現出的現象並非咱們想要的,如:假設咱們想要一個任務每隔10s運行一次,而這個任務每次運行可能須要9秒,這樣表現出來的可能就是每一秒就運行了這個任務;更有甚者,假設咱們想要一個任務每隔10s運行一次,而這個任務每次運行的過程可能要11秒或者20s...,,這時候setInterval就會在執行棧進行累積,隨後連續觸發,爲此咱們可使用setTimeout來實現咱們想要的結果:

!function(){
    console.log("這是一個須要9秒的任務")
    setTimeout(arguments.callee,10000)
}()

 面試題:

for(var i=0;i<3;i++){
    setTimeout(function(){
        console.log(i--) // 3 2 1
    },0)
} 
相關文章
相關標籤/搜索