JavaScript的基礎知識點(面試題)

Mrzhangjwei發表於2016-11-15

1.介紹JavaScript的基本資料型別?

JavaScript的基本型別是: Undefined、Null、Boolean、Number、String

詳細講解: http://www.jianshu.com/p/4841fcc6b4e7

2.JavaScript原型,原型鏈?有什麼特點?

每個物件都會在其內部初始化一個屬性,就是prototype(原型),當我們訪問一個物件的屬性時,如果這個物件內部不存在這個屬性,那麼他就會去prototype裡找這個屬性,這個prototype又會有自己的prototype,
於是就這樣一直找下去,也就是我們平時所說的原型鏈的概念。
關係:instance.constructor.prototype = instance.__proto__
//
特點:JavaScript物件是通過引用來傳遞的,我們建立的每個新物件實體中並沒有一份屬於自己的原型副本,當我們修改原型時,與之相關的物件也會繼承這一改變。
//
當我們需要一個屬性時,JavaScript引擎會先看當前物件中是否有這個屬性,如果沒有的話,就會查詢它的prototype物件是否有這個屬性,如此遞推下去,一致檢索到Object內建物件。

function Func(){}
Func.prototype.name = "Xiaosong";
Func.prototype.getInfo = function() {
  return this.name;
}
var person = new Func();
console.log(person.getInfo());
//"Xiaosong"
console.log(Func.prototype);
//Func { name = "Xiaosong", getInfo = function() }

3.JavaScript如何實現繼承?

  • (1)構造繼承
  • (2)原型繼承
  • (3)例項繼承
  • (4)拷貝繼承
    //
    原型prototype機制或apply和call方法去實現較簡單,建議使用建構函式與原型混合方式。
function Parent() {
  this.name = 'song';
}
function Child() {
  this.age = 28;
}
Child.prototype = new Parent(); //通過原型,繼承了Parent
//
var demo = new Child()l;
alert(demo.age);
alert(demo.name); //得到被繼承的屬性

4.JavaScript建立物件的幾種方式?

javascript建立物件簡單的說,無非就是使用內建物件或各種自定義物件,當然還可以用JSON;但寫法有很多種,也能混合使用。

  • (1)物件字面量的方式
    person={firstname:"Mark",lastname:"Yun",age:25,eyecolor:"black"};
  • (2)用function來模擬無參的建構函式
function Person(){}
var person = new Person(); //定義一個function,如果使用new"例項化",該function可以看作是一個Class
person.name = "Xiaosong";
person.age = "23";
person.work = function() {
  alert("Hello " + person.name);
}
person.work();
  • (3)用function來模擬參建構函式來實現(用this關鍵字定義構造的上下文屬性)
function Person(name,age,hobby) {
  this.name = name; //this作用域:當前物件
  this.age = age;
  this.work = work;
  this.info = function() {
      alert("我叫" + this.name + ",今年" + this.age + "歲,是個" + this.work);
  }
}
var Xiaosong = new Person("WooKong",23,"程式猿"); //例項化、建立物件
Xiaosong.info(); //呼叫info()方法
  • (4)用工廠方式來建立(內建物件)
var jsCreater = new Object();
jsCreater.name = "Brendan Eich"; //JavaScript的發明者
jsCreater.work = "JavaScript";
jsCreater.info = function() {
  alert("我是"+this.work+"的發明者"+this.name);
}
jsCreater.info();
  • (5)用原型方式來建立
function Standard(){}
Standard.prototype.name = "ECMAScript";
Standard.prototype.event = function() {
  alert(this.name+"是指令碼語言標準規範");
}
var jiaoben = new Standard();
jiaoben.event();
  • (6)用混合方式來建立
function iPhone(name,event) {
  this.name = name;
  this.event = event;
}
iPhone.prototype.sell = function() {
  alert("我是"+this.name+",我是iPhone5s的"+this.event+"~ haha!");
}
var SE = new iPhone("iPhone SE","官方翻新機");
SE.sell();

 5.JavaScript作用域鏈?

JavaScript中所有的量都是存在於某一個作用域中的
除了全域性作用域, 每一個作用域都是存在於某個作用域中的
在試圖訪問一個變數時JS引擎會從當前作用域開始向上查詢直到Global全域性作用域停止
例如

var A;//全域性作用域
function B()
{
    var C;//C位於B函式的作用域
    function D()
    {
        var E;//E位於D函式的作用域
        alert(A)
    }
}

當alert(A)時, JS引擎沿著D的作用域, B的作用域, 全域性作用域的順序進行查詢.
這三個作用域組成的有序集合就成為作用域鏈
至於為什麼叫鏈, 你可以理解和連結串列有相似之處, 深層的作用域會能夠訪問到上層作用域, 就如同連結串列中兩個連續節點能夠單向訪問一樣

6.談談this物件的理解。

詳細講解: http://www.cnblogs.com/nuanriqingfeng/p/5794632.html

this是函式執行時自動生成的一個內部物件,只能在函式內部使用,但總指向呼叫它的物件。

通過以下幾個例子加深對this的理解。

  • (1)作為函式呼叫
var name = 'Jenny';
function person() {
    return this.name;
}
console.log(person());  //Jenny

上面這個例子在全域性作用域中呼叫person(),此時的呼叫物件為window,因此this指向window,在window中定義了name變數,因此this.name相當於window.name,為Jenny。

  • (2)作為物件的方法呼叫
var name = 'Jenny';
var obj = {
    name: 'Danny',
    person: function() {
        return this.name;
    }
};
console.log(obj.person());  //Danny

在這個例子中,person()函式在obj物件中定義,呼叫時是作為obj物件的方法進行呼叫,因此此時的this指向obj,obj裡面定義了name屬性,值為Danny,因此this.name = “Danny”。

  • (3)作為建構函式呼叫

作為建構函式呼叫和普通函式呼叫的區別是,建構函式使用new關鍵字建立一個例項,此時this指向例項物件。

function person() {
    return new person.prototype.init();
}
person.prototype = {
    init: function() {
        return this.name;
    },
    name: 'Brain'
};
console.log(person().name); //undefined
  • (4)apply和call

使用apply()和call()可以改變呼叫函式的物件,第一個引數為改變後呼叫這個函式的物件,其中apply()的第二個引數為一個陣列,call的第二個引數為每個引數。

function person() {
    return this.name;
}
var obj = {
    name: 'Jenny',
    age: 18
};
console.log(person.apply(obj));  //Jenny

7.什麼是window物件? 什麼是document物件?

詳情請看參考資料: http://www.w3school.com.cn/jsref/dom_obj_window.asp

簡單來說,document是window的一個物件屬性。
Window 物件表示瀏覽器中開啟的視窗。
如果文件包含框架(frame 或 iframe 標籤),瀏覽器會為 HTML 文件建立一個 window 物件,併為每個框架建立一個額外的 window 物件。
所有的全域性函式和物件都屬於Window 物件的屬性和方法。
document 對 Document 物件的只讀引用。

8.null 和 undefined 有何區別?

null 表示一個物件被定義了,值為“空值”;
undefined 表示不存在這個值。

  • typeof undefined
    //”undefined”
    undefined :是一個表示”無”的原始值或者說表示”缺少值”,就是此處應該有一個值,但是還沒有定義。當嘗試讀取時會返回 undefined;
    例如變數被宣告瞭,但沒有賦值時,就等於undefined。
  • typeof null
    //”object”
    null : 是一個物件(空物件, 沒有任何屬性和方法);
    例如作為函式的引數,表示該函式的引數不是物件;

注意:
在驗證null時,一定要使用 === ,因為 == 無法分別 null 和 undefined

9.寫一個通用的事件偵聽器函式(機試題)。

markyun.Event = {
  //頁面載入完成後
  readyEvent: function(fn) {
      if (fn == null) {
          fn = document;
      }
      var oldonload = window.onload;
      if (typeof window.onload != 'function') {
          window.onload = fn;
      }else{
          window.onload = function() {
              oldonload();
              fn();
          };
      }
  },
  //視能力分別使用 demo0 || demo1 || IE 方式來繫結事件
  //引數:操作的元素,事件名稱,事件處理程式
  addEvent: function(element,type,handler) {
      if (element.addEventListener) {
          //事件型別、需要執行的函式、是否捕捉
          element.addEventListener(type,handler,false);
      }else if (element.attachEvent) {
          element.attachEvent('on' + type, function() {
              handler.call(element);
          });
      }else {
          element['on' + type] = handler;
      }
  },
  //移除事件
  removeEvent: function(element,type,handler) {
      if (element.removeEventListener) {
          element.removeEventListener(type,handler,false);
      }else if (element.datachEvent) {
          element.datachEvent('on' + type,handler);
      }else{
          element['on' + type] = null;
      }
  },
  //阻止事件(主要是事件冒泡,因為IE不支援事件捕獲)
  stopPropagation: function(ev) {
      if (ev.stopPropagation) {
          ev.stopPropagation();
      }else {
          ev.cancelBubble = true;
      }
  },
  //取消事件的預設行為
  preventDefault: function(event) {
      if (event.preventDefault) {
          event.preventDefault();
      }else{
          event.returnValue = false;
      }
  },
  //獲取事件目標
  getTarget: function(event) {
      return event.target || event.srcElemnt;
  },
  //獲取event物件的引用,取到事件的所有資訊,確保隨時能使用event;
  getEvent: function(e) {
      var ev = e || window.event;
      if (!ev) {
          var c = this.getEvent.caller;
          while(c) {
              ev = c.argument[0];
              if (ev && Event == ev.constructor) {
                  break;
              }
              c = c.caller;
          }
      }
      retrun ev;
  }
};

10.[“1”, “2”, “3”].map(parseInt) 答案是多少?

[1,NaN,NaN]

因為 parseInt 需要兩個引數(val,radix),其中 radix 表示解析時用的基數。
map 傳了3個(element,index,array),對應的 radix 不合法導致解析失敗。

11.什麼是閉包(closure),為什麼要用它?

閉包是指有權訪問另一個函式作用域中變數的函式,建立閉包的最常見的方式就是在一個函式內建立另一個函式,通過另一個函式訪問這個函式的區域性變數,利用閉包可以突破作用鏈域,將函式內部的變數和方法傳遞到外部。

閉包特性:

  • (1)函式內再巢狀函式
  • (2)內部函式可以引用外層的引數和變數
  • (3)引數和變數不會被垃圾回收機制回收
//li節點的onclick事件都能正確的彈出當前被點選的li索引
<ul>
  <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() {
          console.log(i+1); //不使用閉包的話,值每次都是4
      }(4);
  }
</script>

12.new操作符具體幹了什麼呢?

  • (1)建立一個空物件,並且 this 變數引用該物件,同時還繼承了該函式的原型。
  • (2)屬性和方法被加入到 this 引用的物件中。
  • (3)新建立的物件由 this 所引用,並且最後隱式的返回 this 。
var obj = {};
obj.__proto__ = Base.prototype;
Base.call(obj);

13.用原生JavaScript的實現過什麼功能嗎?

原生JavaScript能實現的功能,詳情: http://bbs.csdn.net/topics/390565578

14.Javascript中,有一個函式,執行時物件查詢時,永遠不會去查詢原型,這個函式是?

這個函式是: hasOwnProperty
//
JavaScript 中 hasOwnProperty 函式方法是返回一個布林值,指出一個物件是否具有指定名稱的屬性。此方法無法檢查該物件的原型鏈中是否具有該屬性;該屬性必須是物件本身的一個成員。
//
使用方法:
object.hasOwnProperty(proName)
其中引數object是必選項,一個物件的例項。
proName是必選項,一個屬性名稱的字串值。
//
如果 object 具有指定名稱的屬性,那麼JavaScript中hasOwnProperty函式方法返回 true,反之則返回 false。

15.對JSON的瞭解?

JSON(JavaScript Object Notation)是一種輕量級的資料交換格式。
它是基於JavaScript的一個子集。資料格式簡單,易於讀寫,佔用頻寬小。

如: {"age":"12", "name":"back"}

16.Ajax 是什麼? 如何建立一個Ajax?

ajax的全稱:Asynchronous Javascript And XML。
非同步傳輸+js+xml。
所謂非同步,在這裡簡單地解釋就是:向伺服器傳送請求的時候,我們不必等待結果,而是可以同時做其他的事情,等到有了結果它自己會根據設定進行後續操作,與此同時,頁面是不會發生整頁重新整理的,提高了使用者體驗。

  • (1)建立XMLHttpRequest物件,也就是建立一個非同步呼叫物件
  • (2)建立一個新的HTTP請求,並指定該HTTP請求的方法、URL及驗證資訊
  • (3)設定響應HTTP請求狀態變化的函式
  • (4)傳送HTTP請求
  • (5)獲取非同步呼叫返回的資料
  • (6)使用JavaScript和DOM實現區域性重新整理

17.DOM操作——怎樣新增、移除、移動、複製、建立和查詢節點?

  • (1)建立新節點
    createDocumentFragment() //建立一個DOM片段
    createElement() //建立一個具體的元素
    createTextNode() //建立一個文字節點

  • (2)新增、移除、替換、插入
    appendChild()
    removeChild()
    replaceChild()
    insertBefore() //在已有的子節點前插入一個新的子節點

  • (3)查詢
    getElementsByTagName() //通過標籤名稱
    getElementsByName() //通過元素的Name屬性的值(IE容錯能力較強,會得到一個陣列,其中包括id等於name值的)
    getElementById() //通過元素Id,唯一性

18 .call() 和 .apply() 的作用和區別?

1、call,apply都屬於Function.prototype的一個方法,它是JavaScript引擎內在實現的,因為屬於Function.prototype,所以每個Function物件例項(就是每個方法)都有call,apply屬性。既然作為方法的屬性,那它們的使用就當然是針對方法的了,這兩個方法是容易混淆的,因為它們的作用一樣,只是使用方式不同。

2、語法:foo.call(this, arg1,arg2,arg3) == foo.apply(this, arguments) == this.foo(arg1, arg2, arg3);

3、相同點:兩個方法產生的作用是完全一樣的。

4、不同點:方法傳遞的引數不同。

19.陣列物件有哪些原生方法,列舉一下?

詳細用法參考: http://www.jb51.net/article/34711.htm

賦值方法 (Mutator methods): 這些方法直接修改陣列自身.

  • pop 和 push
  • shift 和 unshift
  • splice
  • reverse
  • sort

訪問方法(Accessor methods) : 這些方法只是返回相應的結果,而不會修改陣列本身 ;

  • concat
  • join
  • slice
  • toString
  • indexOf 和 lastIndexOf

迭代方法(Iteration methods):

  • forEach
  • map
  • filter
  • every 和 some
  • reduce 和 reduceRight

20.JavaScript中的作用域與變數宣告提升?

作用域

作用域詳情: http://www.cnblogs.com/lhb25/archive/2011/09/06/javascript-scope-chain.html

任何程式設計語言都有作用域的概念,簡單的說,作用域就是變數與函式的可訪問範圍,即作用域控制著變數與函式的可見性和生命週期。在JavaScript中,變數的作用域有全域性作用域和區域性作用域兩種。

變數宣告,命名,和提升

變數宣告提升詳情: http://blog.csdn.net/sunxing007/article/details/9034253

在javascript,變數有4種基本方式進入作用域:

  • 1.語言內建:所有的作用域裡都有this和arguments;(譯者注:經過測試arguments在全域性作用域是不可見的)
  • 2.形式引數:函式的形式引數會作為函式體作用域的一部分;
  • 3.函式宣告:像這種形式:function foo(){};
  • 4.變數宣告:像這樣:var foo;

相關文章