這是在寫Ajax項(xiàng)目里的購(gòu)物車數(shù)量的更改時(shí)到的:
在下面的例子里茬斧,觸發(fā)事件后a指的是循環(huán)的最后一個(gè)結(jié)果,而不是當(dāng)前觸發(fā)事件的對(duì)象所以以后在循環(huán)里寫事件時(shí)不要直接聲明一個(gè)循環(huán)變量來(lái)觸發(fā)事件因?yàn)檫@樣寫是不準(zhǔn)確的,即使用的是let聲明的變量產(chǎn)生獨(dú)立作用域也不行,例如:
for(let j=0;j
var a=onum[j];
a.oninput=function(){
console.log(this)
console.log(onum[j]);
}
}
準(zhǔn)確的寫法是
for(let j=0;j
onum[j].oninput=function(){
console.log(this)或者
console.log(onum[j]);
}
}
Array.from的方法測(cè)試
/*Array.from方法用于將兩類對(duì)象轉(zhuǎn)為真正的數(shù)組:類似數(shù)組的對(duì)象(array-like object)和可遍歷(iterable)的對(duì)象,常見(jiàn)的類似數(shù)組的對(duì)象是 DOM 操作返回的 NodeList 集合,以及函數(shù)內(nèi)部的arguments對(duì)象*/
?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));//長(zhǎng)度多寫或少寫都會(huì)直接報(bào)錯(cuò)
?var obj6={0:"a",1:"b",2:"c",length:3};
?console.log(Array.from(obj6));//['a', 'b', 'c'];
?/*通過(guò)上面六次測(cè)試可以看出想要使用Array.from方法將對(duì)象轉(zhuǎn)換成數(shù)組逗宜,那么對(duì)象里的屬性名要寫成數(shù)組中的從0開始的下標(biāo)值,屬性值才是下標(biāo)值所代表的元素空骚,下標(biāo)值可以不用引號(hào)裹住纺讲,還要寫上長(zhǎng)度,長(zhǎng)度值不能寫多或少囤屹,有幾個(gè)屬性長(zhǎng)度值就是幾熬甚,否則直接報(bào)錯(cuò)*/
構(gòu)造函數(shù)的幾種寫法、繼承和常犯錯(cuò)誤
構(gòu)造函數(shù)的的寫法和調(diào)用一直是我頭疼的問(wèn)題肋坚,至今我寫的大部分bug都是因?yàn)閷?duì)構(gòu)造函數(shù)掌握的不熟練產(chǎn)生的乡括,剛開始學(xué)的時(shí)候感覺(jué)很簡(jiǎn)單肃廓,但是自己創(chuàng)建、調(diào)用的時(shí)候卻傻眼了诲泌,可以說(shuō)我創(chuàng)建的不是構(gòu)造函數(shù)盲赊,而是大大的bug,所以第一次月考結(jié)束后我就總結(jié)了我所學(xué)到的所有es5敷扫、es6的構(gòu)造函數(shù)哀蘑,忘記了哪個(gè)就去看哪個(gè),不僅容易找到葵第,還能順帶復(fù)習(xí)一下其他的寫法绘迁。
//如果調(diào)用對(duì)象里沒(méi)有的屬性并給這個(gè)屬性賦值
//那么該屬性會(huì)動(dòng)態(tài)的添加到對(duì)象里
//對(duì)象里的方法也可以這樣動(dòng)態(tài)的添加
var obj={"name":"張三"};
obj.age=19;
console.log(obj);//age:19,name:"張三"
//第一種構(gòu)造函數(shù)寫法: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("學(xué)生1",18);
console.log(student1.name);
console.log(student1["name"]);
//正確的調(diào)用:當(dāng)做構(gòu)造函數(shù)調(diào)用
student1["per"]();//第一種寫法:“=”
student1.per();//第一種寫法:“=”
//正確的調(diào)用:當(dāng)做普通函數(shù)調(diào)用
Person("張三",23);
//錯(cuò)誤的輸出
//console.log(student1["per"]());//undefined
//console.log(student1.per());//undefined
//第二種構(gòu)造函數(shù)寫法(es5):json
var json1={"name":"小明",
"age":18,
"sex":"男",
"num":5050,
"num1":123456789,
"zy":"會(huì)計(jì)",
"zwjs":function(){
console.log("第二種寫法:“:”");
//在后臺(tái)打印里如果輸出換行會(huì)被當(dāng)成字符串輸出
?document.write(this.name+"
"+this.age+"
"+this.sex+"
"+this.num+"
"+this.num1+"
"+this.zy)
}
};
//正確的調(diào)用
console.log(json1.name);
json1.zwjs();
//錯(cuò)誤的調(diào)用
//console.log(json1.zwjs());
es5里的構(gòu)造函數(shù)繼承
function Person1(name){
this.name=name;
this.hello=function(){
console.log("我的名字是"+this.name);
}
}
function Person2(name,age){
//繼承步驟:第一步自定義一個(gè)屬性指向所要繼承的構(gòu)造函數(shù)名
this.method=Person1;
//第二步:調(diào)用這個(gè)自定義屬性,也就是調(diào)用所要繼承的構(gòu)造函數(shù)
this.method(name);
//第三步:刪除這個(gè)自定義屬性卒密,因?yàn)榇藭r(shí)這個(gè)函數(shù)已經(jīng)成功繼承
//這個(gè)步驟可寫可不寫
delete this.method;
//這個(gè)是增加的屬性
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方法會(huì)被自動(dòng)調(diào)用
constructor(a,b){
console.log("構(gòu)造函數(shù)被自動(dòng)調(diào)用");
this.a=a;
this.b=b;
console.log("調(diào)用constructor:"+this.a+","+this.b);
}
fangfa1(){
console.log("調(diào)用fangfa1:"+this.a+","+this.b);
}
}
//聲明的對(duì)象aa只會(huì)調(diào)用constructor()方法缀台,因?yàn)檫@個(gè)方法是自動(dòng)調(diào)用的
var aa=new Point(2,3);//構(gòu)造函數(shù)被自動(dòng)調(diào)用 ???調(diào)用constructor:2,3
console.log(typeof aa);//Object
/*聲明的bb不知道為什么類型是undefined,想調(diào)用除constructor()以外的方法就要按照bb的句式寫
?但是這樣寫不僅會(huì)調(diào)用fangfa1(),還會(huì)自動(dòng)調(diào)用constructor()*/
var bb=new Point(2,3).fangfa1();//構(gòu)造函數(shù)被自動(dòng)調(diào)用 ??調(diào)用constructor:2,3 ??調(diào)用fangfa1:2,3
console.log(typeof bb);//undefined
class Point2{
//constructor方法會(huì)被自動(dòng)調(diào)用
constructor(a,b){
console.log("構(gòu)造函數(shù)被自動(dòng)調(diào)用");
this.a=a;
this.b=b;
console.log("調(diào)用constructor:"+this.a+","+this.b);
}
fangfa2(){
return "調(diào)用fangfa2:"+this.a+","+this.b;
}
fangfa3(){
return "你好栅受,世界";
}
}
var cc=new Point2(5,5);
/*如果下面兩句話同時(shí)出現(xiàn)将硝,console.log(cc.fangfa2())打印的結(jié)果只是:調(diào)用fangfa2:5,5
?但如果僅僅只是其中一句話出現(xiàn)恭朗,打印的結(jié)果就是這句話后面的注釋部分*/
console.log(cc);//構(gòu)造函數(shù)被自動(dòng)調(diào)用 ??調(diào)用constructor:5,5 ??Point2?{a: 5, b: 5}
console.log(cc.fangfa2());//構(gòu)造函數(shù)被自動(dòng)調(diào)用 ?調(diào)用constructor:5,5 ??調(diào)用fangfa2:5,5
//class類里的方法名可以是一個(gè)變量,主要是為了用Symbol()類型的變量屏镊,防止重名
let aaa=Symbol();
class Point3{
//constructor方法會(huì)被自動(dòng)調(diào)用
constructor(a,b){
console.log("構(gòu)造函數(shù)被自動(dòng)調(diào)用");
this.a=a;
this.b=b;
console.log("調(diào)用constructor:"+this.a+","+this.b);
}
fangfa2(){
return "調(diào)用fangfa2:"+this.a+","+this.b;
}
//把變量名放入方括號(hào)里
[aaa](){
return "你好,世界";
}
}
var dd=new Point3(3,3);
//如果變量是Symbol類型不能用點(diǎn)運(yùn)算符痰腮,我最開始寫成dd.aaa(),結(jié)果報(bào)錯(cuò)
console.log(dd[aaa]());
//class里的繼承
class Parent{
//constructor方法會(huì)被自動(dòng)調(diào)用
constructor(a,b){
console.log("構(gòu)造函數(shù)被自動(dòng)調(diào)用");
this.a=a;
this.b=b;
console.log("調(diào)用constructor:"+this.a+","+this.b);
}
fangfa2(){
return "調(diào)用fangfa2:"+this.a+","+this.b;
}
}
/*子類必須在constructor方法中調(diào)用super方法而芥,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò)。這是因?yàn)樽宇愖约旱膖his對(duì)象膀值,必須先通過(guò)父類的構(gòu)造函數(shù)完成塑造棍丐,
得到與父類同樣的實(shí)例屬性和方法,然后再對(duì)其進(jìn)行加工沧踏,加上子類自己的實(shí)例屬性和方法歌逢。如果不調(diào)用super方法,子類就得不到this對(duì)象翘狱。*/
class Child extends Parent{
constructor(a,b,c){
super(a,b);//必須先用super關(guān)鍵字調(diào)用父類的方法
this.c=c;
}
fangfa3(){
return this.c+super.fangfa2();
}
}
//在子類傳入新的參數(shù)后父類的參數(shù)值也被改變秘案,意思是父類方法里打印的
//是子類的參數(shù)值
var ee=new Child("我是a","我是b","我是c");
console.log(ee.fangfa3())//我是c調(diào)用fangfa2:我是a,我是b
//php里的構(gòu)造函數(shù)寫法及調(diào)用
class Colors{
var $c1;
function __construct($c1="red"){
echo "自動(dòng)調(diào)用函數(shù)";
$this->c1=$c1;
}
function c2(){
echo "方法二被調(diào)用";
return $this->c1;
}
}
$newcolor=new Colors("pink");
//php文件里調(diào)用除__construct以外的其他方法需要用"->"連接,
//php文件里調(diào)用屬性也要用"->";
//注意千萬(wàn)不要用"."連接潦匈,會(huì)報(bào)錯(cuò)
echo $newcolor->c2();
?>
this的指向
1.在全局環(huán)境中阱高,普通函數(shù)里的this指向的是頂層對(duì)象window(嚴(yán)格模式中,普通函數(shù)內(nèi)部的this是undefined);
2.構(gòu)造函數(shù)中this指的是實(shí)例對(duì)象茬缩;
3.如果對(duì)象的方法里包含this赤惊,this指向的就是方法運(yùn)行時(shí)所在的對(duì)象
4.箭頭函數(shù)中,this指向的是定義時(shí)所在的對(duì)象凰锡,而不是使用時(shí)所在的對(duì)象
封裝函數(shù)里未舟,如果想在方法里的事件內(nèi)部調(diào)用這個(gè)方法外部的方法圈暗,可以在外部聲明一個(gè)變量,var that=this;或者用bind綁定裕膀,又或者直接用箭頭函數(shù)厂置,因?yàn)榧^函數(shù)中,this指向的就是是定義時(shí)所在的對(duì)象魂角,而不是使用時(shí)所在的對(duì)象-->
//1.全局環(huán)境 ??普通函數(shù)(嚴(yán)格模式中禁止this指向全局對(duì)象(window)昵济,避免無(wú)意間創(chuàng)造全局變量)
function fn(){
console.log(this);//返回的是window
}
fn();
function fn2(){
"use strict";//函數(shù)內(nèi)部為嚴(yán)格模式
console.log(this);//返回的是undefined
}
fn2();
//2.構(gòu)造函數(shù)
function Dog(p){
this.p=p;
console.log(this);//由于還沒(méi)給p賦值,所以返回的是Dog?{p: undefined}
}
var xiaohei=new Dog();
//3.對(duì)象 的方法
var obj={
fn3:function(){
console.log(this);//返回的是{fn3: ?}
}
}
obj.fn3();
//bink方法是將函數(shù)內(nèi)的this綁定到指定的對(duì)象野揪,然后返回新的對(duì)象
var dogs={
name:"小黑",
age:"1歲",
//在方法內(nèi)部出現(xiàn)匿名函數(shù)访忿,那么匿名函數(shù)里的this指向的對(duì)象是不確定的
voice:function(){
console.log(this.name);
setTimeout(function(){
console.log(this);//返回的是window
console.log(this.name);//沒(méi)有返回值,因?yàn)檫@里的name是一個(gè)不存在的屬性
//解決方法是console.log(dogs.name);
},1000);
}
}
dogs.voice();
//用bind綁定
/*在這個(gè)例子里新建的對(duì)象person1中一定要有一個(gè)屬性名是say斯稳,并為它賦值海铆,因?yàn)閜erson中的方法act函數(shù)執(zhí)行的是在后臺(tái)打印this.say,要把person1用bind綁定給act挣惰,意思是act會(huì)從
對(duì)象person1中調(diào)用屬性say, 如果沒(méi)有這個(gè)屬性say卧斟,就會(huì)打印出undefined,我第一次寫的時(shí)候就犯了這樣的錯(cuò)誤,
在新建的對(duì)象中隨便定義了一個(gè)屬性名憎茂,卻忘了act方法中執(zhí)行的命令是指定要后臺(tái)打印say屬性的值*/
var person={
say:"你好",
act:function(){
console.log(this.say);
}
}
person.act();
var person1={say:"小萌"};
var aaa=person.act.bind(person1);
aaa();
Ps:程序員之路漫漫珍语,持續(xù)不斷的學(xué)習(xí)和復(fù)習(xí)方能使自己立于不敗之地,翻身成碼農(nóng)之路不遠(yuǎn)了竖幔,決不能中途倒下板乙,功虧一簣。
生活不止眼前的Bug拳氢,還有以后的Bug.....
來(lái)源:千鋒HTML5