JS相關問題
數組去重
function uniq(array){
var temp = []; //一個新的臨時數組
for(var i = 0; i < array.length; i++){
if(temp.indexOf(array[i]) == -1){
temp.push(array[i]);
}
}
return temp;
}
var aa = [1,2,2,4,9,6,7,5,2,3,5,6,5];
console.log(aa)
console.log(uniq(aa))
1、談一談JavaScript作用域鏈
- 當執行一段JavaScript代碼(全局代碼或函數)時,JavaScript引擎會創建一個作用域又稱為執行上下文(Execution Context),在頁面加載后會首先創建一個全局的作用域,然后每執行一個函數,會建立一個對應的作用域,從而形成一條作用域鏈。每個作用域都有一條對應的作用域鏈,鏈頭是全局作用域,鏈尾是當前函數作用域。
- 作用域鏈的作用是用於解析標識符,當函數被創建時(不是執行),會將this,arguments,命名參數和該函數中所有局部變量添加到該當前作用域中,當JavaScript需要查找變量X的時候(這個過程稱為變量解析),它首先會從作用域鏈中的鏈尾也就是當前作用域進行查找是否有X屬性,如果沒有找到就順着作用域鏈繼續查找,直到查找到鏈頭,也就是全局作用域鏈,仍未找到該變量的話,就認為這段代碼的作用域上不存在x變量,並拋出引用錯誤(ReferenceError)的異常。
2、如何理解JavaScript原型鏈
- JavaScript中每個對象都有一個prototype屬性,我們稱之為原型,而原型的值也是一個對象,因此它也有自己的原型,這樣就串聯起來了一條原型鏈,原型鏈的鏈頭是object,它的prototype.proto,值為null。
- 原型鏈的作用是用於對象繼承,函數A的原型屬性(prototype property)是一個對象,當這個函數被用作函數來創建實例時,該函數的原型屬性被作為原型賦值給所有對象實例,比如我們新建一個數組,數組的方法便從數組的原型上繼承而來。
- 當訪問對象的一個屬性時,首先查找對象本身,找到則返回;未找到則繼續查找原型對象的屬性(如果還找不到實際上還會沿着原型鏈向上查找,直至到根)。只要沒有被覆蓋的話,對象原型的屬性就能在所有的實例中找到,若整個原型鏈未找到則返回undefined。
2(1)、JavaScript原型,原形鏈?有什么特點?
- 原型對象也是普通的對象,是對象一個自帶隱式__proto__屬性,原型也有可能有自己的原型,如果一個原型對象的原型為null的話,我們就稱為原型鏈。
- 原形鏈是由一些用來繼承和共享屬性的對象組成的(有限的)對象鏈。
如何查找構造函數和原型中的屬性?
- 構造函數.prototype 查看構造函數的原型屬性
- 實例對象 .__proto__查看實例對象的構造函數的原型
- 實例對象.proto.constructor查看實例對象的構造函數
3、JavaScript如何實現繼承?
-
構造繼承
-
原型繼承
-
實例繼承
-
拷貝繼承
-
原型prototype機制或apply和call方法去實現較簡單,建議使用構造函數與原型混合方式
function Parent(){ this.name = 'wang'; } function Child(){ this.age = 28; } Child.prototype = new Parent();//繼承了Parent,通過原型 var demo = new Child(); alert(demo.age); alert(demo.name);//得到被繼承的屬性
3(1)JavaScript如何實現繼承?
1.借用構造函數。也叫偽造對象或經典繼承。
-
思路:在子類構造函數的內部調用超類型構造函數。可以通過使用apply()和call()方法在新創建的對象上執行構造函數。
-
缺點:方法都在構造函數中定義,函數的復用就無從談起。在超類型的原型中定義的方法,對子類而言也是不可見的,結果所有的類型都只能使用構造函數模式。
function SuperType() { this.colors = ["red","blue","green"]; } function SubType() { SuperType.call(this);//繼承了SuperType } var instance1 = new SubType(); instance1.colors.push("black"); console.log(instance1.colors);//"red","blue","green","black" var instance2 = new SubType(); console.log(instance2.colors);//"red","blue","green"
2.原型鏈繼承
-
思路:借助原型可以基於已有的對象創建對象,同時還不必因此創建自定義類型
-
在object()函數內部,先創建一個臨時的構造函數,然后將傳入的對象作為這個構造函數的原型,最后返回了這個臨時類型的一個新實例==原型鏈繼承的思想可用以下函數來說明
function object(o) { function F(){} F.prototype = o; return new F(); }
例子
var person = {
name:"EvanChen",
friends:["Shelby","Court","Van"];
};
var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");
var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");
console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"
3.組合繼承
- 指的是將原型鏈和借用構造函數的技術組合在一起,從而發揮二者之長。
- 思路:使用原型鏈實現對原型屬性和方法的繼承,通過借用構造函數來實現實例屬性的繼承
- 優點:即通過在原型上定義發法實現了函數復用,又能保證每一個實例都有它自己的數組。
- 組合繼承避免了原型鏈和借用構造函數的缺陷。融合了他們的優點。成為JavaScript中常用的繼承模式
例子
function SuperType(name) {
this.name = name;
this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function() {
console.log(this.name);
}
function SubType(name, age) {
SuperType.call(this,name);//繼承屬性
this.age = age;
}
//繼承方法
SubType.prototype = new SuperType();
Subtype.prototype.constructor = Subtype;
Subtype.prototype.sayAge = function() {
console.log(this.age);
}
var instance1 = new SubType("EvanChen",18);
instance1.colors.push("black");
consol.log(instance1.colors);//"red","blue","green","black"
instance1.sayName();//"EvanChen"
instance1.sayAge();//18
var instance2 = new SubType("EvanChen666",20);
console.log(instance2.colors);//"red","blue","green"
instance2.sayName();//"EvanChen666"
instance2.sayAge();//20
4.寄生式繼承
- 思路:創建一個僅用於封裝繼承過程的函數,該函數在內部以某種方式來增強對象,最后再像真的是它做了所有的工作一樣返回對象
例子
function createAnother(original) {
var clone = object(original); //通過調用函數創建一個新對象
clone.sayHi = function () { //以某種方式來增強這個對象
alert("hi");
};
return clone; //返回這個對象
}
var person = {
name:"EvanChen",
friends:["Shelby","Court","Van"];
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();///"hi"
5.寄生組合式繼承。
-
思路:通過借用構造函數來繼承屬性,通過原型鏈的混成形式來繼承方法
-
本質上,就是寄生式繼承來繼承超類型的原型,然后再將結果指定給子類型的原型
基本模型如下所示
function inheritProperty(subType, superType) { var prototype = object(superType.prototype);//創建對象 prototype.constructor = subType;//增強對象 subType.prototype = prototype;//指定對象 }
例子
function SuperType(name){
this.name = name;
this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function (){
alert(this.name);
};
function SubType(name,age){
SuperType.call(this,name);
this.age = age;
}
inheritProperty(SubType,SuperType);
SubType.prototype.sayAge = function() {
alert(this.age);
}
-
原型prototype機制或apply和call方法去實現較簡單,建議使用構造函數與原型混合方式
function Parent(){ this.name = 'wang'; } function Child(){ this.age = 28; } Child.prototype = new Parent();//繼承了Parent,通過原型 var demo = new Child(); alert(demo.age); alert(demo.name);//得到被繼承的屬性
4、JavaScript的基本數據類型
- Object number function boolean undefined
4(1)、js有哪些內置對象
- 數據封裝類對象:Object、Array、Boolean、Number、String
- 其他對象:FUnction、Arguments、Math、Date、RegExp、Error
JavaScript有幾種類型的值?你能畫一下他們的內存圖?
- 棧:原始數據類型(Undefined,null,Boolean,Number,String)
- 堆:引用數據類型(對象,數組和函數)
- 兩種類型的區別是:存儲位置不同
- 原始類型直接存儲在棧(stack)中的簡單數據段,占據空間小,大小固定,屬於被頻繁使用數據,所以放入棧中存儲;
- 引用數據類型在堆(heap)中的對象,占據空間大,大小不固定。如果存儲在棧中,將會影響程序運行的性能;引用數據類型在棧中存儲了指針,該指針指向堆中該實體的起始地址。當解釋器尋找引用值時,會首先檢索其在棧中的地址,取得地址后從堆中獲得實體
5、例舉3種強制類型轉換和2種隱式類型轉換?
- 強制(parseInt,parseFloat,number)隱式(== ===)
6、split()join()的區別
- 前者是切割成數組的形式,后者是將數組轉換成字符串
7、數組方法pop()push()unshift()shift()
- pop()尾部刪除 push()尾部添加
- shift()頭部刪除 unshift()頭部添加
8、IE和DOM事件流的區別
- 執行順序不一樣,
- 參數不一樣、
- 事件加不加on、
- this指向問題
9、ajax請求的時候get和post方式的區別
- 一個在url后面 一個放在虛擬載體里面
- 有大小限制
- 安全問題
- 應用不同:一個是論壇等只需要請求的,一個是類似需改 密碼的
10、IE的標准下有哪些兼容性的寫法
Var ev = ev || window.event
document.documentElement.clientWidth || document.body.clientWidth
Var target = ev.srcElement||ev.target
11、ajax請求時,如何解釋json數據
- 使用eval parse,鑒於安全性考慮,使用parse更靠譜
12、事件委托是什么
- 讓利用事件冒泡的原理,讓自己的所觸發的事件,讓他的父元素代替執行!
12(1)請說說事件委托機制?這樣做有什么好處?
- 事件委托,就是某個事件本來該自己干的,但是自己不干,交給別人來干,就叫事件委托。打個比方:一個button對象,本來自己需要監控自身的點擊事件,但是自己不來監控這個點擊事件,讓自己的父節點來監控自己的點擊事件。
好處
- A,提高性能:例如,當有很多li同時需要注冊時間的時候,如果使用傳統方法來注冊事件的話,需要給每一個li注冊事件。然而如果使用委托事件的話,就只需要將事件委托給該一個元素即可。這樣就能提高性能
- B,新添加的元素還會有之前的事件
13、閉包是什么,有什么特性,對頁面有什么影響?簡要介紹你理解的閉包
- 閉包就是能夠讀取其他函數內部變量的函數
- “官方”的解釋是:所謂“閉包”,指的是一個擁有許多變量和綁定了這些變量的環境的表達式(通常是一個函數),因而這些變量也是該表達式的一部分。
通俗的講:就是函數a的內部函數b,被函數a外部的一個變量引用的時候,就創建了一個閉包。 - ①.封閉性:外界無法訪問閉包內部的數據,如果在閉包內聲明變量,外界是無法訪問的,除非閉包主動向外界提供訪問接口;
- ②.持久性:一般的函數,調用完畢之后,系統自動注銷函數,而對於閉包來說,在外部函數被調用之后,閉包結構依然保存在
- 系統中,閉包中的數據依然存在,從而實現對數據的持久使用。
優點:
- ① 減少全局變量。
- ② 減少傳遞函數的參數量
- ③ 封裝;
缺點:
- 使用閉包會占有內存資源,過多的使用閉包會導致內存溢出等.
14、添加 插入 替換 移除 到某個接點的方法
- obj.appendChild()
- obj.insertBefore()
- obj.replaceChild()
- obj.removeChild()
14(1)、DOM怎樣添加、移動、復制、創建和查找節點
// 創建新節點
createDocumentFragment() //創建一個DOM片段
createElement() //創建一個具體的元素
createTextNode() //創建一個文本節點
// 添加、移除、替換、插入
appendChild()
removeChild()
replaceChild()
insertBefore() //在已有的子節點前插入一個新的子節點
// 查找
getElementsByTagName() //通過標簽名稱
getElementsByName() //通過元素的Name屬性的值(IE容錯能力較強,會得到一個數組,其中包括id等於name值的)
getElementById() //通過元素Id,唯一性
15、""和"="的不同
- 前者會自動轉換類型,后者不會
15(1)請說出和=的區別?
-
==判斷內容是否相等不比較類型
console.log(1=="1");//true
-
===判斷內容相等且類型也相等
console.log(1==="1"); //false
16、編寫一個b繼承a的方法
function A(name){
this.name = name;
this.sayHello = function(){alert(this.name+” say Hello!”);};
}
function B(name,id){
this.temp = A;
this.temp(name); //相當於new A();
delete this.temp;
this.id = id;
this.checkId = function(ID){alert(this.id==ID)};
}
17、如何阻止事件冒泡和默認事件
function stopBubble(e)
{
if (e && e.stopPropagation)
e.stopPropagation()
else
window.event.cancelBubble=true
}
return false
17(1)什么是事件冒泡/捕獲
事件冒泡:子元素事件的觸發會影響父元素事件
- 開關事件冒泡:
- A,開啟事件冒泡:element.addEventListener(eventName,handler,false);
- B,關閉事件冒泡:假設傳統方式事件的返回值為e,就可以通過e.stopPropagation()來關閉事件冒泡;
事件捕獲:父元素的事件會影響子元素的事件;
- 開啟事件捕獲:element.addEventListener(eventName,hadler,true)
18、下面程序執行后彈出什么樣的結果?
function fn() {
this.a = 0;
this.b = function() {
alert(this.a)
}
}
fn.prototype = {
b: function() {
this.a = 20;
alert(this.a);
},
c: function() {
this.a = 30;
alert(this.a);
}
}
var myfn = new fn();
myfn.b();
myfn.c();
19、談談this對象的理解
- this是js的一個關鍵字,隨着函數使用場合不同,this的值會發生變化。
- 但是有一個總原則,那就是this指的是調用函數的那個對象。
- this一般情況下:是全局對象Global。作為方法調用,那么this就是指這個對象
19(1)、this對象的理解
- this總是指向函數的直接調用者(而非間接調用者);
- 如果有new關鍵字,this指向new出來的那個對象;
- 在事件中,this指向觸發這個事件的對象,特殊的是,IE中attachEcent中this總是指向全局對象Window;
this對象的理解
- this是一個關鍵字,它代表函數運行時,自動生成一個內部對象,只能在函數內部使用
- 1.作為純粹的函數調用this指向全局對象
- 2.作為對象的方法調用this指向調用對象
- 3.作為構造函數被調用this指向新的對象(new會改變this的指向)
- 4.apply調用this指向apply方法的第一個參數
- this總是指向函數的直接調用者(而並非間接調用者);
- 如果有new關鍵字,this指向new出來的那個對象;
- 在事件中,this指向這個事件的對象,特殊的是,IE中的attachEvent中的this總是指向全局對象Window;
20、下面程序的結果
function fun(n,o) {
console.log(o)
return {
fun:function(m){
return fun(m,n);
}
};
}
var a = fun(0); a.fun(1); a.fun(2); a.fun(3);
var b = fun(0).fun(1).fun(2).fun(3);
var c = fun(0).fun(1); c.fun(2); c.fun(3);
//答案:
//a: undefined,0,0,0
//b: undefined,0,1,2
//c: undefined,0,1,1
21、下面程序的輸出結果
var name = 'World!';
(function () {
if (typeof name === 'undefined') {
var name = 'Jack';
console.log('Goodbye ' + name);
} else {
console.log('Hello ' + name);
}
})();
22、了解Node?Node的使用場景都有哪些?
- 高並發,聊天,實時消息推送
23、介紹下最常用的一款框架
- jQuery,rn,angular等
24、對於前端自動化構建工具有了解嗎?簡單介紹一下
- Gulp,Grunt等
25、說一下什么是JavaScript的同源策略?
- 一段腳本只能讀取來自同一來源的窗口和文檔的屬性,這里的同一源指的是主機名,協議和端口號的組合
26、eval是指做什么的?
- 它的功能是把對應的字符串解析成JS代碼並運行;
- 應該避免使用eval,不安全,非常耗性能(2次、一次解析成js語句,一次執行);
- 由JSON字符串轉換為JSON對象的時候可以用eval,val obj=eval('('+str+')')
26(1)eval是做什么的?
- 它的功能是把對應的字符串解析成js代碼並運行;
- 應該避免使用eval,不安全,非常好性能(2次,一次解析成js語句,一次執行);
- 由JSON字符串轉換為JSON對象的時間可以用eval,var obj=eval('('+str+')');
27.請列舉字符串操作的方法?
- chartCodeAt方法返回一個整數,代表指定位置字符的Unicode編碼;
- chartAt方法返回指定索引位置處的字符。如果超出有效范圍的索引值返回空字符串;
- slice方法返回字符串的片段
- substring方法返回位於String對象中指定位置的子字符串。
- substr方法返回一個從指定位置開始的指定長度的子字符串。
- indexOf方法返回String對象內第一次出現子字符串位置。如果沒有找到子字符串。則返回-1;
- lastIndexOf方法返回String對象中字符串最后出現的位置。如果沒有匹配到子字符串,則返回-1;
- search方法返回與正則表達式查找內容匹配的第一個字符串的位置;
- concat方法返回字符串值,該值包含了兩個或多個提供的字符串的連接;
- split將一個字符串分割為子字符串,然后將結果作為字符串數組返回;
28、null和undefined的區別?
null是表示"無"的對象,轉為數值時為0;undefined是表示"無"的原始值,轉為數值時為NaN。
Q1
- 1、變量被聲明了,但沒有賦值,就等於undefined。
- 調用函數時
- 2,應該提供的參數沒有提供該參數等於undefined。
- 3、對象沒有賦值的屬性,該屬性的值為undefined.
- 4、函數沒有返回值時,默認返回undefined。
Q2
- 1、作為函數的參數,表示該函數的參數不是對象
- 2、作為對象原型鏈的終點。
什么是window對象?什么是document對象?
- window對象是指瀏覽器打開的窗口
- document對象是Document對象(HTML文檔對象)的一個只讀引用,window對象的一個屬性。
null,undefined的區別?
-
null 表示一個對象是"沒有值"的值,也就是值為"空";
-
undefined 表示一個變量聲明了沒有初始化(賦值);
-
undefined不是一個有效的JSON,而null是;
-
undefined的類型(typeof)是object;
-
JavaScript將未賦值的變量默認值設為undefined;
-
JavaScript從來不會將變量設為null。它是用來讓程序員表明某個用var聲明的變量時沒有值的。
-
typeof undefined
//"undefined" undefined:是一個表示"無"的原始值或者說表示"缺少值",就是此處應該有一個值,但是還沒有定義。當嘗試讀取時會返回undefined; 例如變量被聲明了。但沒有賦值時,就等於undefined
-
typeof null
//"object" null:是一個對象(空對象,沒有任何屬性和方法); 例如作為函數的參數,表示該函數的參數不是對象;
-
注意:
在驗證null時,一定要使用===,因為==無法分別null和undefined null==undefined//true null===undefined//false
-
再來一個例子:
null Q:有張三這個人么? A:有! Q:張三有房子么? A:沒有! undefined Q:有張三這個人么? A:有! Q: 張三有多少歲? A: 不知道(沒有被告訴)
29、new操作符具體干了什么呢?
- 1、創建一個空對象,並且this變量引用該對象,同時還繼承了該函數的原型。
- 2、屬性和方法被加入到this所引用的對象中。
- 3、新創建的對象由this所引用,並且最后隱式的返回this。
30、JSON的了解?
- JSON(JavaScript Object Notation)是一種輕量級的數據交換格式。它是基於JavaScript的一個子集。數據格式簡單,易於讀寫,占用帶寬小。
- 格式:采用鍵值對,例如:{age:12,name:
'back'}
30(1)JSON的了解?
-
json(JavaScript Object Notation)是一種輕量級的數據交換格式。
-
它是基於JavaScript的一個子集。數據格式簡單,易於讀寫,占用帶寬小
如:{"age":"12",""}
-
json字符串轉換為json對象
var obj=eval('('+str+')'); var obj=str.parseJSON(); var obj=JSON.parse(str);
-
JSON對象轉換為JSON字符串
var last=obj.toJSONString(); var last=JSON.stringify(obj);
31、call()和play()的區別和作用?
- 1、apply()函數有兩個參數:第一個參數是上下文,第二個參數是參數組成的數組。如果上下文是null,則使用全局對象代替。
- 如:function.apply(thi是,[1,2,3]);
- 2、call()的第一個參數是上下文,后續是實例傳入的參數序列。
- 如:function.call(this,1,2,3);
32、JS數組去重
以下是展示三種方法
Array.prototype.unique1 = function () {
var n = []; //一個新的臨時數組
for (var i = 0; i < this.length; i++) //遍歷當前數組
{
//如果當前數組的第i已經保存進了臨時數組,那么跳過,
//否則把當前項push到臨時數組里面
if (n.indexOf(this[i]) == -1) n.push(this[i]);
}
return n;
}
Array.prototype.unique2 = function()
{
var n = {},r=[]; //n為hash表,r為臨時數組
for(var i = 0; i < this.length; i++) //遍歷當前數組
{
if (!n[this[i]]) //如果hash表中沒有當前項
{
n[this[i]] = true; //存入hash表
r.push(this[i]); //把當前數組的當前項push到臨時數組里面
}
}
return r;
}
Array.prototype.unique3 = function()
{
var n = [this[0]]; //結果數組
for(var i = 1; i < this.length; i++) //從第二項開始遍歷
{
//如果當前數組的第i項在當前數組中第一次出現的位置不是i,
//那么表示第i項是重復的,忽略掉。否則存入結果數組
if (this.indexOf(this[i]) == i) n.push(this[i]);
}
return n;
}
33、js操作獲取和設置cookie
//創建cookie
function setCookie(name, value, expires, path, domain, secure) {
var cookieText = encodeURIComponent(name) + '=' + encodeURIComponent(value);
if (expires instanceof Date) {
cookieText += '; expires=' + expires;
}
if (path) {
cookieText += '; expires=' + expires;
}
if (domain) {
cookieText += '; domain=' + domain;
}
if (secure) {
cookieText += '; secure';
}
document.cookie = cookieText;
}
//獲取cookie
function getCookie(name) {
var cookieName = encodeURIComponent(name) + '=';
var cookieStart = document.cookie.indexOf(cookieName);
var cookieValue = null;
if (cookieStart > -1) {
var cookieEnd = document.cookie.indexOf(';', cookieStart);
if (cookieEnd == -1) {
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
}
return cookieValue;
}
//刪除cookie
function unsetCookie(name) {
document.cookie = name + "= ; expires=" + new Date(0);
}
34、GET和POST的區別,何時使用POST?
- GET:一般用於信息獲取,使用URL傳遞參數,對發送信息的數量也有限制,一般在2000個字符
- POST:一般用於修改服務器上的資源,對發送的信息沒有限制
- GET方式需要使用Request.QueryString來獲取變量的值,而POST方式通過R額quest.Form來獲取變量的值,也就是說GET是通過地址欄傳值,而Post是通過提交表單來傳值。
- 然而,在以下情況中,請使用POST請求:
- 無法使用緩存文件(更新服務器上的文件或數據庫)
- 向服務器發送大量數據(POST沒有數據量限制)
- 發送包含未知字符的用戶輸入時,POST比GET更穩定也更可靠
35、Falsh、Ajax各自的優缺點,在使用中如何取舍?
- Falsh適合處理多媒體,矢量圖形、訪問機器;對css、處理文本上不足,不容易被搜索。
- Ajax對css、文本支持很好、支持搜索;多媒體、矢量圖形、機器訪問不足。
- 共同點:與服務器的無刷新傳遞消息、用戶離線和在線狀態,操作DOM
36、ajax過程
- 1、創建XMLHttpRequest對象,也就是創建一個異步調用對象。
- 2、創建一個新的HTTP請求,並指想向該HTTP請求的方法、URL及驗證信息。
- 3、設置響應HTTP請求狀態變化的函數。
- 4、發送HTTP請求。
- 5、獲取異步調用返回的數據。
- 6、使用JavaScript和DOM實現局部刷新。
js延遲加載的方式有哪些?
- defer和async,動態創建DOM方式(用得最多),按需異步載入js
如何解決跨越問題?
- jsonp,iframe,window.name,window.postMessage
new操作符具體干了什么呢?
-
1.創建了一個空對象,並且this變量引用該對象,同時還繼承了該函數的原型。
-
2.屬性和方法被加入到this引用的對象中。
-
3.新創建的對象由this所引用,並且最后隱式的返回this。
var obj={}; obj.__proto__=Base.prototype; Base.call(obj);
面向對象和類的區別?
- 簡單的說類是對象的模板。
- 在js中沒有類,所以在js中所謂的類就是構造函數,對象就是有構造函數創建出來的實例對象。面向對象就是使用面向對象的方式處理問題,面向對象是向過程進行封裝。
- 對象的概念,面向對象編程的程序實際就是多個對象的集合,我們可以把所有的事物都抽象成對象,在程序設計中可以看作:對象=屬性+方法。屬性就是對象的數據,而方法就是對象的行為
- 類的概念,類是對象的模板,而對象是類的實例化。舉個例子,汽車設計圖可以看作是類,而具體的汽車就是對象。再比如有一個類是表示人,然后可以通過人這個模板來實例化出張三,李四...
面向對象有三大特性
- 抽象性,需要通過核心數據和特定環境才能描述對象的具體意義
- 封裝性,封裝就是講數據和功能組合到一起,在js中對象就是鍵值對的集合,對象將屬性和方法封裝起來,方法將過程封裝起來
- 繼承性,將別人的屬性的方法成為自己的,傳統繼承基於模板(類),js中繼承基於構造函數
在js的計時器運行原理是怎樣的,為什么可以觸發計時器效果?計時器是多線程嗎?
- 1.JavaScript引擎只有一個線程,強迫異步事件排隊等待被執行。
- 2.setTimeout和setInterval本質上不同的地方是他們如何執行異步代碼的。
- 3.如果一個定時器正在執行的時候被阻塞了,那么它將會被推遲到下一個可能的執行點,這既是使得延遲時間有可能會超過聲明定時器時設置的值。
- Interval如果有足夠的時間來執行(大於指定的延遲),那么它將會無延遲的一個緊接着一個執行。
- 原理
- 計時器通過設定一定的時間段(毫秒)來異步的執行一段代碼。因為JavaScript是一個單線程,計時器提供了一種繞過這種語言限制來執行代碼的能力。
- 總結:
- 計時器是單線程的,需要等待上一個執行完,如果上一個沒有執行完,下一個需要延遲執行,直到上一個執行完