面向對象學習總結

1.Object.create的模擬javascript

 

//Object.create 該方法是ES5新增的方法,因此IE8以前不支持html

 

function create(obj){java

function F(){}面試

F.prototype=obj;數組

return new F();瀏覽器

}函數

 

var obj={工具

val:1測試

};this

var o=create(obj);

console.log(o.val);//1

</script>

2.create兼容性處理

 

<script>

//兼容IE8,若是瀏覽器Object上沒有create方法,

//那麼本身添加一個模擬的

if(!Object.create){

Object.create=function(obj){

function F(){}

F.prototype=obj;

return new F();

}

}

//說明,若是瀏覽器支持Object.create方法,則優先使用Object.create方法

//若是不支持,則本身實現一個相似的方法,可是不保證和Object.create一致

function create (obj){

if(Object.create){

Object.create(obj);

}else{

function F(){}

F.prototype=obj;

return new F();

}

}

</script>

  •  

3.函數的原型鏈

 

<script>

//全部的函數都直接繼承Function.prototype

//1.函數有兩個原型相關的屬性

function fn(){}

//構造函數fn==>Function.prototype==>Object.prototype==>null

//構造函數的原生對象fn.prototype==>Object.prototype==>null

 

//Array==>Function.prototype==>Object.prototyp==>null

//Array.prototype==>Object.prototype==>null

 

 

//Function==>Function.prototype==>Object.prototype==>null

//Function.prototype==>Object.prototype==>null

 

 

//Object==>Function.prototype==>Object.prototype==>null

//Object.prototype==>null

 

</script>

4.copy繼承與對象回收的問題

 

<script>

function extend(o,o2){

for(var key in o2){

o[key]=o2[key];

}

}

//obj指向的對象,只要被obj變量或其餘變量或其餘屬性引用着

//那麼obj指向的那個對象永遠不會被垃圾回收機制回收掉

var obj={

val:1

};

var o=new Object();

extend(o,obj);//obj自身沒有任何改變

 

obj=null;

//這時候,obj以前指向的那個對象,沒有任何變量或者屬性引用它了

//那麼這個對象未來就會被回收

 

var o2={

a:1

};

//吧一個字面量對象的屬性copy到o2裏面,copy完畢以後

//這個字面量對象並無任何變量或屬性引用他

//那麼這個字面量對象未來就會被釋放掉

extend(o2,{

b:2

});

 

</script>

5.關於對象的類型

 

<script>

/*

* 全部的數組都是Array類型;

* 全部的函數都是Function類型;

* 全部的日期都是Date類型。

* */

</script>

6.instanceof

 

<script>

//instanceof 是誰的實例

//做用:判斷一個對象是否是另外一個構造函數的實例

//語法: 對象 instanceof 構造函數

 

function Dog(){}

var beibei=new Dog();

//beibei是Dog的實例

//beibei==>Dog.prototype(Dog構造函數原生的原型對象)==>Object.prototype==>null

//這個原生的原型對象在beibei的原型鏈結構中存在

console.log(beibei instanceof Dog);//true

 

 

Dog.prototype={

run:function(){

console.log('跑');

}

}

//beibei==>Dog.prototype(Dog構造函數原生的原型對象)==>Object.prototype==>null

//Dog.prototype如今存儲的是自定義的原型對象

//這個自定義的原型對象不在beibei的原型鏈結構中

console.log(beibei instanceof Dog);//false

beibei.run();//報錯 不能再建立對象實例以後定義函數

//由於實例繼承的仍然是原生的原型對象

 

//發現剛開始是true,後面修改了構造函數的原型屬性後

//結果是false,說明instanceof運算符實力很深

 

//instanceof運算符的運算規則:

//判斷左邊對象的原型鏈結構中,是否存在右邊構造函數的顯示原型對象

</script>

7.instanceof面試題

 

<script>

//函數的原型鏈結構

//Function==>Function.prototype==>Object.prototype==>null

console.log(Function instanceof Function);//true

console.log(Function instanceof Object);//true

 

//Object的原型鏈結構

//Object==>Function.prototype==>Object.prototype==>null

console.log(Object instanceof Function);//true

console.log(Object instanceof Object);//true

 

 

// 自定義構造函數系列的面試題

function Dog(){}

var beibei=new Dog();

console.log(beibei instanceof Dog);//true

 

Dog.prototype={};

console.log(beibei instanceof Dog);//false

 

 

 

// 內置的構造函數系

var arr=[];

console.log(arr instanceof Array);//true

console.log(arr instanceof Function);//false

console.log(arr instanceof Object);//true

 

 

 

console.log(Object.prototype instanceof Object);//false

// 這個是false,即Object.prototype繼承的是null;

// 和Object的顯式原型對不上。

 

instanceOf考題

 

<script>

//copy函數

function extend(obj1,obj2){

for(var key in obj2){

obj1[key]=obj2[key];

}

}

 

//考題1系列

function Person(){}

//給原生原型添加一個屬性

Person.prototype.eat='吃';

var zs=new Person();

console.log(zs instanceof Person); //true

console.log(zs instanceof Function); //false

console.log(zs instanceof Object);//true

// zs==>person.prototype==>object.prototype==>null

 

 

// 考題2系列

// 覆寫原生原型對象

Person.prototype = {

run: '跑'

};

var xgl = new Person();

console.log(zs instanceof Person); //false

console.log(xgl instanceof Person); //true

//xgl==>person.prototype==>object.prototype==>null

// console.log(xgl);

 

// 考題3系列

function Student() {}

var zj = new Student();

extend(Student.prototype, Person.prototype);

//zj==>Student.prototype==>object.prototype==>null

// console.log(zj);

console.log(zj instanceof Student); //true

console.log(zj instanceof Person); //false

console.log(zs instanceof Student); //false

console.log(zs instanceof Person); //false

console.log(xgl instanceof Student); //false

console.log(xgl instanceof Person); //true

 

var sl = new Student();

console.log(sl instanceof Student); //true

console.log(sl instanceof Person); //false

//sl==>Student.prototype==>object.prototype==>null

console.log(sl);

 

 

// 考題4系列

var ll = Object.create(Student.prototype);

//ll==>Student.prototype==>object.prototype==>null

// console.log(ll);

console.log(ll instanceof Student); //true

console.log(ll instanceof Person); //false

 

 

// 考題5系列

Student.prototype = new Person();

var tj = new Student();

//tj==>Student.prototype==>object.prototype==>null

// console.log(tj);

console.log(ll instanceof Student); //false

console.log(ll instanceof Person); //false

console.log(tj instanceof Student); //true

console.log(tj instanceof Person); //true

 

// 考題6系列

// new Date ==>Date.prototype==>Object.prototype==>null

 

console.log(new Date instanceof Function); //false

console.log(new Date instanceof Object); //true

 

// new Function ==>Function.prototype==>Object.prototype==>null

 

console.log(new Function instanceof Function); //true

console.log(new Function instanceof Object); //true

 

// Number ==>Function.prototype==>Object.prototype==>null

 

console.log(Number instanceof Function); //true

console.log(Number instanceof Object); //true

 

// Function ==>Function.prototype==>Object.prototype==>null

console.log(Function instanceof Function); //true

console.log(Function instanceof Object); //true

 

 

// Object ==>Function.prototype==>Object.prototype==>null

 

console.log(Object instanceof Function); //true

console.log(Object instanceof Object); //true

</script>

 

</script>

 

老師給出的答案 詳細解釋(instanceof 考題)

 

<script>

// copy函數

function extend(obj1, obj2) {

for(var key in obj2) {

obj1[key] = obj2[key];

}

}

 

// 考題1系列

console.log('------------------1-----------------');

function Person() {}

// 給原生原型添加一個屬性

Person.prototype.eat = '吃';

var zs = new Person();

console.log(zs instanceof Person); // true

console.log(zs instanceof Function); // false

console.log(zs instanceof Object); // true

 

// zs ==> Person.prototype(原生的原型對象) ==> Object.prototype ==> null

 

// 考題2系列

// 覆寫原生原型對象

console.log('------------------2-----------------');

Person.prototype = {

run: '跑'

};

var xgl = new Person();

console.log(zs instanceof Person); // false

console.log(xgl instanceof Person); // true

 

// xgl ==> Person.prototype(自定義的原型對象) ==> Object.prototype ==> null

 

// 考題3系列

console.log('------------------3-----------------');

function Student() {}

var zj = new Student();

extend(Student.prototype, Person.prototype);

 

// zs ==> Person.prototype(原生的原型對象) ==> Object.prototype ==> null

// xgl ==> Person.prototype(自定義的原型對象) ==> Object.prototype ==> null

// zj ==> Student.prototype(原生的原型對象)==> Object.prototype ==> null

 

console.log(zj instanceof Student); // true

console.log(zj instanceof Person); // false

console.log(zs instanceof Student); // false

console.log(zs instanceof Person); // false

console.log(xgl instanceof Student); // false

console.log(xgl instanceof Person); // true

 

var sl = new Student();

console.log(sl instanceof Student); // true

console.log(sl instanceof Person); // false

 

// sl ==> Student.prototype(原生的原型對象)==> Object.prototype ==> null

 

// 考題4系列

console.log('------------------4-----------------');

var ll = Object.create(Student.prototype);

 

// ll ==> Student.prototype(原生的原型對象)==> Object.prototype ==> null

 

console.log(ll instanceof Student); // true

console.log(ll instanceof Person); // false

 

// 考題5系列

console.log('------------------5-----------------');

Student.prototype = new Person();

var tj = new Student();

 

// ll ==> Student.prototype(原生的原型對象)==> Object.prototype ==> null

// tj ==> Student.prototype(Person的實例) ==> Person.prototype(自定義的原型對象) ==> Object.prototype ==> null

 

console.log(ll instanceof Student); // false

console.log(ll instanceof Person); // false

console.log(tj instanceof Student); // true

console.log(tj instanceof Person); // true

 

// 考題6系列

console.log('------------------6-----------------');

 

// new Date ==> Date.prototype ==> Object.prototype ==> null

 

console.log(new Date instanceof Function); // false

console.log(new Date instanceof Object); // true

 

// new Function ==> Function.prototype ==> Object.prototype ==> null

 

console.log(new Function instanceof Function); // true

console.log(new Function instanceof Object); // true

 

// Number ==> Function.prototype ==> Object.prototype ==> null

 

console.log(Number instanceof Function); // true

console.log(Number instanceof Object); //true

 

// Function ==> Function.prototype ==> Object.prototype ==> null

 

console.log(Function instanceof Function); // true

console.log(Function instanceof Object); // true

 

// Object ==> Function.prototype ==> Object.prototype ==> null

 

console.log(Object instanceof Function); // true

console.log(Object instanceof Object); // true

</script>

 

8.Object原型上的方法介紹

 

<script>

//Object.prototype原型上的方法:

//這些方法,全部擁有原型鏈結構的對象都能使用

//hasOwnProperty

//for in

//isPrototypeOf

//propertyIsEnumerable

//toLocaleString

//toString

//valueOf

 

//1.hasOwnProperty has有 own本身的 property 屬性

//方法的做用:判斷一個屬性是否是本身的(判斷本身有沒有某個屬性)

//上訴語言中的本身,指的是調用hasOwnProperty的那個對象

//語法:對象.hasOwnProperty(屬性名)

 

 

var obj={

val:1

};

console.log(obj.hasOwnProperty('val'));//true

//val是obj對象本身的屬性,因此結果爲true

console.log(obj.hasOwnProperty('toString'));//false

//toString不是obj對象本身的屬性,因此結果爲false

 

 

//自定義的屬性是可枚舉的,可以被for in遍歷出來

//內置的屬性是不可枚舉的,不可以被for in遍歷出來

 

function extend(o,o2){

for(var key in o2){

//for in能夠把一個對象繼承的屬性給遍歷出來

if(o2.hasOwnProperty(key)){

//若是是本身的屬性,才copy到第一個對象中

o[key]=o2[key];

}

}

}

Object.prototype.itcast='傳智播客';

var obj={

val:100

};

var o={};

//把obj對象本身的屬性copy到o中

extend(o,obj);

console.log(o);//object{val:100}

console.log(obj);//object{val:100}

console.log(o.itcast);//傳智播客 可是o也能夠訪問itcast屬性

// ——————————————————————————————————————————————————--

//2.for in 遍歷對象的屬性,它不光能夠遍歷該對象本身的屬性

//還能遍歷這個對象所繼承的屬性

//固然必須知足一個條件,(這些必須是可枚舉的)

Array.prototype.it='IT';

Object.prototype.itcast='itcast';

var arr=[];

for(var key in arr){

console.log(key);//it和itcast都能打印出來

}

// ..............................................

//3.isPrototypeOf

//is是 prototype 原型 of 誰的

//該方法的做用:判斷調用isprototypeOf方法的對象,在不在另外一個對象的原型鏈中

//這個方法和instanceof有點相似,都和原型鏈相關,不過他們的語法規則相差很大

//語法:對象.isPrototypeOf(另外一個對象)

 

var arr=[];

console.log(Array.prototype.isPrototypeOf(arr));//true

//Array.prototype這個對象在arr的原型鏈中,因此結果爲true

 

 

/*---------------------------------------------------------*/

 

//4.propertyIsEnumerable

//property屬性 is是 enumerable枚舉

//該方法的做用:判斷一個屬性是否是可枚舉的,又判斷這個屬性是否是本身的

//因此該方法通常解釋爲是hasOwnProperty的增強版本

//語法: 對象.propertyIsEnumerable(屬性名)

 

 

var o={

a:1

};

Object.prototype.it='IT';

console.log(o.propertyIsEnumerable('a'));//true

console.log(o.propertyIsEnumerable('it'));//false

 

console.log(o.hasOwnProperty('a'));//true

console.log(o.hasOwnProperty('it'));//false

 

 

console.log(Object.prototype.propertyIsEnumerable('it'));//true

console.log(Object.prototype.propertyIsEnumerable('toString'));//false

 

console.log(Object.prototype.hasOwnProperty('it')); // true

console.log(Object.prototype.hasOwnProperty('toString')); // true

/*---------------------------------------------------------*/

 

//5.toLocalString

//做用:根據對象的類型,調用該對象本地的toString方法

//arr==>Array.prototype==>Object.prototype==>null

var arr=[1,2,3];

//由於Array.prototype上面存在toLocalString這個方法

//爲了可以讓arr調用Object.prototype上面的toLocalString這個方法

//因此手動的把Object.prototype上面的toLocaleString這個方法添加到arr自身。

arr.toLocaleString=Object.prototype.toLocaleString;

console.log(arr.toLocaleString());//1,2,3

console.log(arr.toString());//1,2,3

 

/*---------------------------------------------------------*/

//6.toString

//不一樣的構造函數 .prototype都有屬於本身的toString方法

//這裏說的是Object.prototype上的toString

//做用:返回一個相似於這樣的字符串'[object 類型名]'

//這個字符串中包含了對象的類型(通常用來區分ECMAScript內置的10大對象類型)。

 

//打印'[object object]'

var obj={};

console.log(obj.toString());//[object object]

 

//打印'[object Array]'

var arr=[];

arr.toString=Object.prototype.toString;

console.log(arr.toString());//[object Array]

 

 

// 打印'[object Date]'

var date=new Date();

date.toString=Object.prototype.toString;

console.log(date.toString());//[object Date]

 

// 打印'[object Math]'

console.log(Math.toString());//[object Math]

 

// 打印'[object Boolean]'

var boo = new Boolean();

boo.toString = Object.prototype.toString;

console.log(boo.toString());//[object Boolean]

 

 

// 打印'[object HTMLBodyElement]'

document.body.toString = Object.prototype.toString;

console.log(document.body.toString());//[object HTMLBodyElement]

 

// 打印'[object Object]'

function Dog() {}

var gougou = new Dog();

console.log(gougou.toString());

// 根據上訴測試,發現Object.prototype上的toString能夠用來獲取內置對象的類型。

 

/*---------------------------------------------------------*/

//7.value of

做用:返回對象自身

console.log(obj.valueOf());//Object{}

console.log(obj===obj.valueOf());//true

</script>

9.靜態成員和實例成員

 

<script>

//1.靜態成員(類成員):

//添加到構造函數身上的屬性或者方法,能夠稱之爲靜態成員

//通常添加到構造函數身上的方法,都是工具性方法

// 函數也是對象,對象不必定是函數。

// 數組也是對象,對象不必定是數組。

// 對象是泛指,函數和數組是對象具體的類型。

 

function Person(){

// 表明某個實例本身的最大年齡

this.MAX_AGE=230;

}

Person.MAX_AGE=300;

// 靜態成員的特色,不用建立實例,就能夠訪問這個屬性。

console.log(Person.MAX_AGE);//300

 

//通常添加到構造函數身上的方法,都是工具性方法

Person.extend=function(obj){

for(var key in obj){

this[key]=obj[key];

}

}

 

// ..................................................

 

//2.實例成員

//添加給實例的屬性和方法就叫實例成員

//供實例使用的屬性和方法也叫實例成員

 

function Dog(name,age){

// 這是添加給未來的實例的,那麼這就是實例成員

this.name=name;

this.age=age;

}

// 這是添加給Dog本身的,實例不能使用,那麼這就是靜態成員。

Dog.MAX_AGE=24;

// 這是供實例使用的方法,那麼這也是實例成員

Dog.prototype.run=function(){

console.log('跑');

}

</script>

10.函數的屬性

 

<script>

//函數默認自有的一些屬性

//1.prototype:爲了讓實例繼承的對象

//2.__proto__:函數本身繼承的對象

//3.name:函數的名字,若是是匿名函數,那麼值是一個空字符串

//4.arguments:一個表明實參的對象,這個屬性會在函數被調用時從新賦值

//5.length:函數形參的個數

//6.caller:調用該函數的函數,這個屬性會在函數被調用時從新賦值

 

/*---------------------------length屬性------------------------*/

  函數的length屬性:用來獲取形參的個數

function f(){}

console.log(f.length);//0

 

function f2(a,b){}

console.log(f2.length);//2

 

arguments的length屬性:用來獲取傳入的實參的個數 

function count(a,b){

if(arguments.length<count.length){

throw'生氣了,爲何不給我傳入要求的參數';

}

console.log(a+b);

}

count(1,2);//3

// count(1);報錯 11函數的屬性.html:27 Uncaught 生氣了,爲何不給我傳入要求的參數 這是咱們手動添加的報錯

 

/*-----------------------------arguments屬性----------------------*/

function fn(){

// 這種方式淘汰了

console.log(fn.arguments);//[1,2]

// 這種是經常使用的方式,arguments後來被提高爲關鍵字了,能夠直接使用

console.log(arguments);//[1,2]

}

fn(1,2);

/*-----------------------------arguments的callee屬性----------------------*/

//arguments.callee屬性,返回被調用的函數自身

function add(){

//返回add自身

console.log(arguments.callee);// function add(){//返回add自身console.log(arguments.callee);}

 

}

add();

//callee通常用在匿名函數的遞歸裏

(function(){

//調用本身

arguments.callee();

})();

 

/*-----------------------------caller屬性----------------------*/

function f3(){

// 返回調用個人那個函數

console.log(f3.caller);//null 由於調用f3的是window 但window不是函數 因此值爲null

}

!function fff() {

// 返回調用個人那個函數,若是調用個人不是函數,那麼就返回null

console.log(fff.caller);// function fff() {// 返回調用個人那個函數,若是調用個人不是函數,那麼就返回nullconsole.log(fff.caller);f3();}

f3();

}();

//!()表示函數自調

 

 

</script>

11.in 運算符

 

<script>

//in運算符單獨使用時,能夠用來判斷對象可以使用某屬性

//單獨使用和枚舉沒有關係了,就看對象能不能使用某個屬性

//屬性名 in 對象

 

var o={

val:100

};

Object.prototype.itcast='czbk';

console.log('val'in o);//true

console.log('itcast' in o);//true

console.log('toString' in o);//true

</script>

12.delete運算符

 

<script>

//delete能夠用來刪除對象的屬性

//語法:delete 對象.屬性名

//語法:delete 對象[屬性名]

//delete能夠刪除一些全局屬性或方法,例如delete window.alert
//delete也能夠刪除沒有經過var定義的全局變量
//經過var定義的全局變量沒法刪除

 

var o={

a:1,

b:2

};

console.log(o);//Object {a: 1, b: 2}

console.log(o.a);//1

console.log(o.b);//2

 

//刪除o的a屬性

delete o.a;

console.log(o.a);//undefined

console.log(o);//Object {b: 2}

delete o['b'];//也能夠用這種方式刪除,但要給裏面的屬性名加單引號,要否則就成了變量

console.log(o.b);

 

//刪除o的b屬性

delete o.b;

console.log(o.b);//undefined

console.log(o);//Object {}

</script>

13.Function&eval

 

<script id="jsTem" type="liubei">

var a = 1;

console.log(a);

</script>

<script >

//正常狀況下,<script type="javascript">

// var a=1;

// console.log(a);//1

//可是咱們若是修改script裏面的type屬性

//即 <script id="jsTem" type="liubei">

//此時j就不能在打印

// var a=1;

// console.log(a);

 

 

// Function 是一個內置的構造函數,能夠用來建立函數

// 語法:new function(arg1,arg2,arg3...,)

// 參數所有都是字符串

//這種方式至關於下面的方式,可是這種方式比較簡單便捷

// function cound(a,b){

// console.log(a+b);

// }

 

//用new是正常的使用方式

var fn=new Function('a','b','console.log(a+b);');

fn(1,2)//3

//不用new也ok

var fn2=Function('a','b','console.log(a+b);');

fn(10,20);//30

 

 

 

//Function能夠把字符串轉換爲函數的代碼體

//這樣就能夠經過Function執行字符串代碼

var jsTem=document.getElementById('jsTem').innerHTML;

Function(jsTem)();//1

 

 

 

//eval,也能夠執行字符串代碼,相比Function比較直接

//由於傳入eval的字符串會立刻執行,而Function先返回給你一個函數

//須要你手動調用一下才會執行

eval(jsTem);//1

eval('console.log(10)');//10

eval('console.log(103)')//103

相關文章
相關標籤/搜索