07.25 HTML5前端for循環結果的指向學習分享

HTML5前端for循環結果的指向學習分享

這是在寫Ajax項目裡的購物車數量的更改時到的:

在下面的例子裡,觸發事件後a指的是循環的最後一個結果,而不是當前觸發事件的對象所以以後在循環裡寫事件時不要直接聲明一個循環變量來觸發事件因為這樣寫是不準確的,即使用的是let聲明的變量產生獨立作用域也不行,例如:

for(let j=0;j<onum.length>

var a=onum[j];

a.oninput=function(){

console.log(this)

console.log(onum[j]);

}

}

/<onum.length>

準確的寫法是

for(let j=0;j<onum.length>

onum[j].oninput=function(){

console.log(this)或者

console.log(onum[j]);

}

}

/<onum.length>

Array.from的方法測試

/*Array.from方法用於將兩類對象轉為真正的數組:類似數組的對象(array-like object)和可遍歷(iterable)的對象,常見的類似數組的對象是 DOM 操作返回的 NodeList 集合,以及函數內部的arguments對象*/

var obj1={"a":"1","b":"2","c":"3",length:3};

console.log(Array.from(obj1));//[undefined, undefined, undefined]

var obj2={"1":"a","2":"b","3":"c",length:3};

console.log(Array.from(obj2));//[undefined, "a", "b"]

var obj3={"0":"a","1":"b","2":"c",length:3};

console.log(Array.from(obj3));//['a', 'b', 'c']

var obj4={"0":"a","1":"b","2":"c"};

console.log(Array.from(obj4));//[];

// var obj5={"0":"a","1":"b","2":"c",,length:6};

// console.log(Array.from(obj5));//長度多寫或少寫都會直接報錯

var obj6={0:"a",1:"b",2:"c",length:3};

console.log(Array.from(obj6));//['a', 'b', 'c'];

/*通過上面六次測試可以看出想要使用Array.from方法將對象轉換成數組,那麼對象裡的屬性名要寫成數組中的從0開始的下標值,屬性值才是下標值所代表的元素,下標值可以不用引號裹住,還要寫上長度,長度值不能寫多或少,有幾個屬性長度值就是幾,否則直接報錯*/

構造函數的幾種寫法、繼承和常犯錯誤

構造函數的的寫法和調用一直是我頭疼的問題,至今我寫的大部分bug都是因為對構造函數掌握的不熟練產生的,剛開始學的時候感覺很簡單,但是自己創建、調用的時候卻傻眼了,可以說我創建的不是構造函數,而是大大的bug,所以第一次月考結束後我就總結了我所學到的所有es5、es6的構造函數,忘記了哪個就去看哪個,不僅容易找到,還能順帶複習一下其他的寫法。

//如果調用對象裡沒有的屬性並給這個屬性賦值

//那麼該屬性會動態的添加到對象裡

//對象裡的方法也可以這樣動態的添加

var obj={"name":"張三"};

obj.age=19;

console.log(obj);//age:19,name:"張三"

//第一種構造函數寫法:es5

function Person(name,age){

this.name=name;

this.age=age;

console.log(this.name,this.age);

this.per=function(){

console.log("第一種寫法:“=”");

}

}

var student1=new Person("學生1",18);

console.log(student1.name);

console.log(student1["name"]);

//正確的調用:當做構造函數調用

student1["per"]();//第一種寫法:“=”

student1.per();//第一種寫法:“=”

//正確的調用:當做普通函數調用

Person("張三",23);

//錯誤的輸出

//console.log(student1["per"]());//undefined

//console.log(student1.per());//undefined

//第二種構造函數寫法(es5):json

var json1={"name":"小明",

"age":18,

"sex":"男",

"num":5050,

"num1":123456789,

"zy":"會計",

"zwjs":function(){

console.log("第二種寫法:“:”");

//在後臺打印裡如果輸出換行會被當成字符串輸出 document.write(this.name+"
"+this.age+"
"+this.sex+"
"+this.num+"
"+this.num1+"
"+this.zy)

}

};

//正確的調用

console.log(json1.name);

json1.zwjs();

//錯誤的調用

//console.log(json1.zwjs());

es5裡的構造函數繼承

function Person1(name){

this.name=name;

this.hello=function(){

console.log("我的名字是"+this.name);

}

}

function Person2(name,age){

//繼承步驟:第一步自定義一個屬性指向所要繼承的構造函數名

this.method=Person1;

//第二步:調用這個自定義屬性,也就是調用所要繼承的構造函數

this.method(name);

//第三步:刪除這個自定義屬性,因為此時這個函數已經成功繼承

//這個步驟可寫可不寫

delete this.method;

//這個是增加的屬性

this.age=age;

this.me=function(){

console.log(name,age);

}

}

var p1=new Person1("張三");

var p2=new Person2("李四",18);

p1.hello();

p2.hello();

p2.me();

//第三種方法class類:es6

class Point{

//constructor方法會被自動調用

constructor(a,b){

console.log("構造函數被自動調用");

this.a=a;

this.b=b;

console.log("調用constructor:"+this.a+","+this.b);

}

fangfa1(){

console.log("調用fangfa1:"+this.a+","+this.b);

}

}

//聲明的對象aa只會調用constructor()方法,因為這個方法是自動調用的

var aa=new Point(2,3);//構造函數被自動調用 調用constructor:2,3

console.log(typeof aa);//Object

/*聲明的bb不知道為什麼類型是undefined,想調用除constructor()以外的方法就要按照bb的句式寫

但是這樣寫不僅會調用fangfa1(),還會自動調用constructor()*/

var bb=new Point(2,3).fangfa1();//構造函數被自動調用 調用constructor:2,3 調用fangfa1:2,3

console.log(typeof bb);//undefined

class Point2{

//constructor方法會被自動調用

constructor(a,b){

console.log("構造函數被自動調用");

this.a=a;

this.b=b;

console.log("調用constructor:"+this.a+","+this.b);

}

fangfa2(){

return "調用fangfa2:"+this.a+","+this.b;

}

fangfa3(){

return "你好,世界";

}

}

var cc=new Point2(5,5);

/*如果下面兩句話同時出現,console.log(cc.fangfa2())打印的結果只是:調用fangfa2:5,5

但如果僅僅只是其中一句話出現,打印的結果就是這句話後面的註釋部分*/

console.log(cc);//構造函數被自動調用 調用constructor:5,5 Point2{a: 5, b: 5}

console.log(cc.fangfa2());//構造函數被自動調用 調用constructor:5,5 調用fangfa2:5,5

//class類裡的方法名可以是一個變量,主要是為了用Symbol()類型的變量,防止重名

let aaa=Symbol();

class Point3{

//constructor方法會被自動調用

constructor(a,b){

console.log("構造函數被自動調用");

this.a=a;

this.b=b;

console.log("調用constructor:"+this.a+","+this.b);

}

fangfa2(){

return "調用fangfa2:"+this.a+","+this.b;

}

//把變量名放入方括號裡

[aaa](){

return "你好,世界";

}

}

var dd=new Point3(3,3);

//如果變量是Symbol類型不能用點運算符,我最開始寫成dd.aaa(),結果報錯

console.log(dd[aaa]());

//class裡的繼承

class Parent{

//constructor方法會被自動調用

constructor(a,b){

console.log("構造函數被自動調用");

this.a=a;

this.b=b;

console.log("調用constructor:"+this.a+","+this.b);

}

fangfa2(){

return "調用fangfa2:"+this.a+","+this.b;

}

}

/*子類必須在constructor方法中調用super方法,否則新建實例時會報錯。這是因為子類自己的this對象,必須先通過父類的構造函數完成塑造,

得到與父類同樣的實例屬性和方法,然後再對其進行加工,加上子類自己的實例屬性和方法。如果不調用super方法,子類就得不到this對象。*/

class Child extends Parent{

constructor(a,b,c){

super(a,b);//必須先用super關鍵字調用父類的方法

this.c=c;

}

fangfa3(){

return this.c+super.fangfa2();

}

}

//在子類傳入新的參數後父類的參數值也被改變,意思是父類方法裡打印的

//是子類的參數值

var ee=new Child("我是a","我是b","我是c");

console.log(ee.fangfa3())//我是c調用fangfa2:我是a,我是b

//php裡的構造函數寫法及調用

class Colors{

var $c1;

function __construct($c1="red"){

echo "自動調用函數";

$this->c1=$c1;

}

function c2(){

echo "方法二被調用";

return $this->c1;

}

}

$newcolor=new Colors("pink");

//php文件裡調用除__construct以外的其他方法需要用"->"連接,

//php文件裡調用屬性也要用"->";

//注意千萬不要用"."連接,會報錯

echo $newcolor->c2();

?>

this的指向

//1.全局環境 普通函數(嚴格模式中禁止this指向全局對象(window),避免無意間創造全局變量)

function fn(){

console.log(this);//返回的是window

}

fn();

function fn2(){

"use strict";//函數內部為嚴格模式

console.log(this);//返回的是undefined

}

fn2();

//2.構造函數

function Dog(p){

this.p=p;

console.log(this);//由於還沒給p賦值,所以返回的是Dog{p: undefined}

}

var xiaohei=new Dog();

//3.對象 的方法

var obj={

fn3:function(){

console.log(this);//返回的是{fn3: ƒ}

}

}

obj.fn3();

//bink方法是將函數內的this綁定到指定的對象,然後返回新的對象

var dogs={

name:"小黑",

age:"1歲",

//在方法內部出現匿名函數,那麼匿名函數里的this指向的對象是不確定的

voice:function(){

console.log(this.name);

setTimeout(function(){

console.log(this);//返回的是window

console.log(this.name);//沒有返回值,因為這裡的name是一個不存在的屬性

//解決方法是console.log(dogs.name);

},1000);

}

}

dogs.voice();

//用bind綁定

/*在這個例子裡新建的對象person1中一定要有一個屬性名是say,併為它賦值,因為person中的方法act函數執行的是在後臺打印this.say,要把person1用bind綁定給act,意思是act會從 對象person1中調用屬性say, 如果沒有這個屬性say,就會打印出undefined,我第一次寫的時候就犯了這樣的錯誤, 在新建的對象中隨便定義了一個屬性名,卻忘了act方法中執行的命令是指定要後臺打印say屬性的值*/

var person={

say:"你好",

act:function(){

console.log(this.say);

}

}

person.act();

var person1={say:"小萌"};

var aaa=person.act.bind(person1);

aaa();

Ps:程序員之路漫漫,持續不斷的學習和複習方能使自己立於不敗之地,翻身成碼農之路不遠了,決不能中途倒下,功虧一簣。

生活不止眼前的Bug,還有以後的Bug.....


分享到:


相關文章: