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();
什麼是閉包(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>
執行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
隨着瀏覽器的升級,大部分瀏覽器對於閉包引發的循環引用問題都可以順利解決。但IE9以前使用非本地JavaScript對象實現DOM對象,對於Javascript對象跟DOM對象使用不一樣的垃圾收集器。因此閉包在IE的這些版本中發生循環引用時便會致使內存泄露。
參考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
基於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());
編寫一個方法求一個字符串的字節長度,假設:一個英文字符佔用一個字節,一箇中文字符佔用兩個字節
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
這裏把符合如下條件的對象稱爲僞數組:
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
//十進制轉其餘 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));
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) }