寫在開頭:
為了學習方便,js程序分成兩個階段學習,JS初級和js高級階段,js高級有很多需要理解的概念,重在理解!讓我們愉快的開始學習吧。
一、面向對象
1、對象,JavaScript是一種面向對象編程(OOP)語言。一種編程語言可以被稱為面向對象的,它為開發者提供了四種基本功能:
1)抽象
2)繼承(父級對子級功能的開放和共享)
3)封裝(將抽象得到的數據和行為相結合,形成一個整體,對外隱藏屬性和實現細節,只對外提供接口)
4)多態(同一操作作用于同類但不同的對象上面,可以產生不同的解釋和不同的執行結果
對象是由屬性和方法。如果屬性包含一個函數,它被認為是一個對象的方法,否則,該屬性被認為是一個屬性。
2、創建對象方法(自定義對象):
1)字面量法
字面量創建對象
var car = {
name:"didi",
age:5
run:function(){
console.log("跑的快")}
};
2)new+構造函數
var obj = new Object();
3)工廠模式創建
創建工廠函數
function factory(name,age){
var newObj = {};
newObj.name = name;
newObj.age = age;
newObj.say = function(){
console.log(this.name);};
return newObj;}
使用構造函數創建對象
var person = factory("tom",28);
4)動態原型方式創建
3、對象屬性的增刪改查
Obj[屬性名]注意區別!屬性加雙引號,變量不加Obj[變量]
car.name =“baoma”
4、對象屬性的getter()、setter()
我們知道,對象屬性是由名字、值和一組特性(attribute)構成的。在ECMAScript 5中,屬性值可以用一個或兩個方法替代,這兩個方法就是getter和setter。由getter和setter定義的屬性稱做「存取器屬性(accessor property)」,它不同于「數據屬性(data property)」,數據屬性只有一個簡單的值。
當程序查詢存取器屬性的值時,JavaScript 調用getter方法。這個方法的返回值就是屬性存取表達式的值。當程序設置一個存取器屬性的值時,JavaScript 調用setter方法,將賦值表達式右側的值當做參數傳入setter。從某種意義上講,這個方法負責「設置」屬性值。可以忽略setter方法的返回值。
和數據屬性不同,存取器屬性不具有可寫性(writable attribute)。如果屬性同時具有getter和setter方法,那么它是一個讀/寫屬性。如果它只有getter方法,那么它是一個只讀屬性。如果它只有setter方法,那么它是一個只寫屬性,讀取只寫屬性總是返回undefined。定義存取器屬性最簡單的方法是使用對象直接量語法的一種擴展寫法。例如:
varo = {// 普通的數據屬性data_prop: value,// 存取器屬性都是成對定義的函數get accessor_prop() {/*這里是函數體 */},? ? set accessor_prop(value) {/* 這里是函數體*/}};
存取器屬性定義為一個或兩個和屬性同名的函數,這個函數定義沒有使用function關鍵字,而是使用get或set。注意,這里沒有使用冒號將屬性名和函數體分隔開,但在函數體的結束和下一個方法或數據屬性之間有逗號分隔。
set可以用于修改私有屬性
get獲取值
5、對象序列化(serialization)是指將對象的狀態轉換為字符串,也可將字符串還原為對象。ECMAScript 5提供了內置函數JSON.stringify()和JSON.parse()。
6、for-in循環遍歷對象
7、屬性查找:首先在自身中查找,如果沒有沿著原型鏈逐級向上查找,最后沒有找到返回undefined
8、靜態方法:給構造函數添加的方法和屬性。
二、高級函數
1、Js中函數屬于一等公民,幾乎可以出現在任何場景中。(作為參數、函數嵌套函數、函數作為返回值
2、函數分類:官方定義的函數(輸出函數都document、alert()、console.log()、輸入函數prompt()、變量類型的轉換函數Number()、parsenInt()、paeseFloat()、Boolean()、isNaN()、數學函數、Math.random();Math.random()*(n-m)+m、DOM document.getElementByid())、構造函數、自定義函數
js中絕大數的函數的原型都是object類型的,只有一個例外,就是Function他的原型是一個function
3、創建函數方式:
1)function關鍵字聲明function add(){}
2)字面量方式聲明var say = function(){}
3)使用new Function創建函數對象var add = new Function(“a”,”b”);
var function_name = new Function(arg1, arg2, ..., argN, function_body)
創建ab數值互換函數注意形參需使用字符串
var fn = new Function("a", "b", "a = a + b; b = a - b; a = a - b; console.log(a); console.log(b);");
fn(10, 20);
4、函數作用域:形參、實參
Js中是以函數作為局部變量和全局變量區分,沒有塊元素。
變量聲明、函數聲明
5、this典型場景:
6、構造函數,特殊的函數,用于創建同類對象
function Person(){
thhis.name = name;
this.age = age;
this.say(){
}
}
7、使用new關鍵字執行構造函數(實例對象)
var p1 = new Pereson();
8、構造函數和普通函數的區別:
1)首字母大寫
2)內部使用this關鍵字處理屬性賦值邏輯
3)構造函數不使用return關鍵字返回新對象
4)使用new關鍵字執行函數
構造函數與實例:實例是new加構造函數創建的對象,新對象叫做構造函數的實例。實例與構造函數之間是多對一的關系。
eg:一個Person函數可以創建無數個Person實例p1 p2 ...pn
new做的一些事兒:new在堆區開辟一片空間用來保存對象;返回堆區對象的引用地址。
三、原型:作用是為所有實例提供公共的空間,原型內的屬性可以提供給構造函數所有實例復用。
1、每一個函數對象都有一個私有原型屬性prototype,Person.prototype這個值是一個object類型的對象
實例(對象)都有一個__proto__屬性指向構造函數的原型prototype
2、hasOwnProperty()函數:用來判斷某個屬性是否是自身的私有屬性,是返回true, 原型中的屬性或不存在返回false
isprototype()判斷一個對象是否是另一個對象的原型。
In關鍵字可以判斷某個屬性對象是都可用,準確說對象自身私有屬性或者原型屬性總存在該屬性返回true
3、原型鏈:原型通過繼承關系鏈接到一起,組成的鏈型結構,叫做原型鏈。
原型是函數prototype屬性對應的對象,而多個構造函數相互繼承,將彼此的原型對象進行關聯,組成了一條鏈型結構。
原型鏈從下級函數實例的__ptoto__開始 ?原型鏈的頂端Object.prototype.__proto__
4、繼承
繼承方式:原型繼承、借用構造函數、組合繼承、ES6方法繼承
1)原型方式繼承:
Student.prototype = new Person();
將上級函數的實例,賦值給下級函數的原型
繼承目的:下級函數的實例提供多個可共用的原型
原型方式繼承:
優點:通過原型方式繼承,底層函數可以逐級向上復用上級函數原型空間
缺點:下級函數無法復用上級函數的私有屬性初始邏輯,上級函數實例的私有屬性會進入到下級函數的原型中,即使是undefined也會被當做有效屬性查找
偽造、借用構造函數方式的繼承:
優點:可以實現多繼承,還可以復用上級函數私有屬性初始化邏輯
缺點:此種繼承和原型無關,下級函數實例無法復用上級函數的原型
基于以上兩種繼承方式的優缺點,人們創造而第三種繼承方式: 組合方式繼承
原型繼承:
將上級函數的實例,賦值給下級函數的原型
繼承目的:下級函數的實例提供多個可共用的原型
注意!constructor屬性位于函數對象中。是原型默認的兩個屬性之一,他的默認值是原型所屬的函數。
當對函數原型進行覆蓋型操作時,注意必須修正constructor屬性(原型繼承)
2)借用構造函數繼承(經典繼承)
關鍵代碼借用call()、apply()函數
function Student(name, age, stuNum, legs, eyes){
Person.call(this, name, age);
Animal.apply(this, [legs, eyes]);
// this.name = name;
// this.age = age;
this.stuNum = stuNum;}
call、appl繼承作用:
可以延長作用域借用構造函數方式支持多繼承
區別:兩者主要差異在于傳參call將函數需要的參數在第二個參數開始按順序傳遞,而apply只能講參數封裝成數組傳給函數
3)組合繼承(原型和組合繼承)
function Fruit(color, taste, size){
this.color = color;
this.taste = taste;
this.size = size;}
Fruit.prototype.grow = function(){
console.log("小蘋果長大了!");}
創建蘋果構造函數
function Apple(color, taste, size, price){
復用上級函數私有屬性初始化邏輯
Fruit.call(this, color, taste, size);
this.price = price;}
使用原型繼承方式,連接上下級函數原型
Apple.prototype = new Fruit();
Apple.prototype.bad = function(){
console.log("再不吃就爛了!!!");}
創建實例測試繼承效果
var apple = new Apple("red", "sweet", "big", 100);
apple.grow();
console.log(apple);
1、可以延長作用域借用構造函數方式支持多繼承
2、區別:兩者主要差異在于傳參call將函數需要的參數在第二個參數開始按順序傳遞,而apply只能講參數封裝成數組傳給函數
3、基于借用、偽造構造函數方式的繼承,并沒有關聯上下級函數的原型,而是僅僅讓下級函數借用了上級函數初始化私有屬性的代碼。
4)ES6繼承
class Person{
constructor(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;}
walk(){
console.log("你好嗎");}
}
class Student extends Person{
constructor(name,age,sex,school,stu_id){
super(school,stu_id);
this.stu_id = stu_id;
this.school = school;}
run(){
console.log("400米");}
}
var student4 = new Student("北大","7號");
console.log(student4);
student4.run();
四、Ajax:是一種瀏覽器到服務器端通信技術,通常使用腳本發送異步請求。
1、通信原理(核心步驟)
ajax通信過程控制,是通過監聽readyState狀態碼來實現的,而監聽是通過onreadystatechange事件監聽屬性完成的
readyState分5個狀態
0):xhr對象創建
1):open初始化完成
2):send請求發送
3):開始接收返回數據
4):數據接收完畢
注意!//XMLHttpRequest在絕大多數瀏覽器下都支持。而IE低版本下(ie6)不支持該構造函數,需要使用ActiveXObject該構造函數需要使用對應的參數構造出通信對象["MSXML.XMLHttp.6.0","MSXML.XMLHttp.3.0","MSXML.XMLHttp"]
2、get和post的區別:get與post是http通信協議下兩種想后臺發送請求的方式。post允許傳遞參數相比get更大,get是k級別的數據量post是m級別的數據量;
post傳參數據放在數據報文內部,而get參數拼接在url后面,post更安全;
get相比post方式請求更快,理論上能快一倍
3、jsonp跨域手段
4、baiduTemplate Javascript模板引擎:
應用在前端模版系統或則后端JavaScript的環境發布頁面,它提供了一套模版語法,用戶可以寫一個模版區塊,每次根據傳入的數據生成對應數據產生的Html,渲染不同界面效果;它的優點:愈發簡單,學習成本極低,開發效率提升很大,采用javascript的原生語法,所以效率比較高, 默認HTML轉義(防XSS攻擊),并且支持包括URL轉義等多種轉義,變量未定義自動輸出為空,防止頁面錯亂,功能強大,如分隔符可自定等多種功能。
五、動畫
1、計時器的寫法(輪播圖)
2、鼠標、鍵盤位置元素(推箱子游戲)
3、游戲(碰撞檢測)
4、jQuery動畫
六、一些重要的概念
1、變量聲明提升:js是一種腳本語言,執行前沒有編譯過程,但是有預編譯階段。預編譯以代碼塊或文件為單位,首先檢查語法錯誤,再做做變量聲明提升,最后做函數聲明提升。當一個區塊內代碼執行前,js引擎會對該區域代碼進行預編譯,將所有變量聲明提升到代碼最頂端,初始化為undefined。
2、函數聲明提升:預編譯階段,當前作用域下所有函數對象會被創建完成。
預編譯作用:
1).語法錯誤檢查,如果有錯誤,不再執行后續操作
2).變量聲明提升
3).函數聲明提升
3、函數柯里化:為函數執行固定的參數固定參數從第二個參數開始按順序傳入。
核心思想:為在復用原函數邏輯代碼基礎上,為函數指定固定的參數。
function curry(fn){
var args = [].slice.call(arguments, 1);
return function(){
使用slice函數將實參維數組轉化為數組,下一部拼接
var innerArgs = [].slice.call(arguments);
固定參數列表拼接自定義參數列表
var argsFinal = args.concat(innerArgs);
執行原有函數 只不過參數列表已經被替換為新列表
return fn.apply(null, argsFinal)}}
4、同源策略:瀏覽器限制動態訪問非同源資源內容。處于安全考慮下不允許使用ajax等異步加載技術非同源內容,也防止外部內容惡意注入。同源三大要素:協議、ip和端口
5、回調函數:作為主函數達到某些固定條件才會執行的函數。通常作為主函數的參數傳入主函數中。
6、C/S通信客戶端/服務端通信 ?客戶端網游和服務器B/S瀏覽器/服務端通信 百度等
通信是端與端的數據交互
7、閉包:外部函數返回的,持有外部函數變量的,內部函數。
8、匿名函數:通常出現在不需要使用函數名執行函數的場景。
9、垃圾回收:垃圾回收清理內存中無用的對象,釋放內存空間簡稱GC。
主流垃圾回收方式有兩種:標記清除是目前js主流垃圾回收機制,清除邏輯: 首先標記內存中所有對象,檢查不再運行環境中的對象,取消標記,檢查后 清除不帶有標記的對象,釋放對應空間。
2)引用計數 因為少數IE核心中bom dom對象仍使用c系列語言實現,所以保留其引用計數垃圾回收方式 邏輯:當一個對象在內存存在一個引用,計數為1每多一個引用計數加一,當垃圾回收執行時,會檢查并銷毀計數為0的對象
js不推薦程序員主動觸發垃圾回收,依賴js核心自動的垃圾回收周期
垃圾回收中所有代碼執行暫停,所以不建議程序員自助調用回收函數觸發回收。
垃圾回收優化:采用分批次分優先級等算法,盡量減少單次垃圾回收耗時。
10、事件委托:通過上級節點監聽事件處理下級節點事件。
事件冒泡:當前節點觸發某類事件時,也會從當前節點開始逐級先上,觸發上級節點的同類事件。event對象的target屬性可以返回觸發當前的dom對象
事件委托優點:可以減少頁面綁定事件數量,提高頁面性能
當子節點動態變化 無需重新處理
例子:
document.getElementById("div1").onclick = function(e){
e = e || window.event;
var curDom = e.target.id;
switch(curDom){
case "btn1":
console.log("這是按鈕1");
break;
case "btn2":
console.log("這是按鈕2");
break;
case "btn3":
console.log("這是按鈕3");
break;
default:
break;}}}
11、原型鏈:原型通過繼承關系鏈接到一起,組成的鏈型結構,叫做原型鏈。
原型是函數prototype屬性對應的對象,而多個構造函數相互繼承,將彼此的原型對象進行關聯,組成了一條鏈型結構。
12、匿名函數:沒有名字的函數。通常不使用函數名調用此類函數。
13、自執行函數:匿名自執行函數,在函數內部創建了一個獨立的命名空間,空間聲明變量不會對外部作用域產生污染。外部不會干擾影響內部空間。
七、寫在結尾:
歸納整理的不夠全面,有待完善。
期待js初級程序設計出爐!