早上偷跑内容:
关于获取body元素的方法
document.getElementById("id") 通过id或许元素
document.getElementByClassName("class") 通过class获取元素
这里注释一下,这里如果去接收document.getElementByClassName获取的元素,会自动建立一个数组HTMLcollection,来储存类名。
而id并不是这样,id作为全局唯一的值,会作为唯一对象保存,并且无法直接用控制台console.log(),或者write()输出,这样做的话会显示object HTMLHeadingElement,必须用innerHTML输出,可以理解为id接受的话会以特殊方法装载,而innerHTML就是钥匙。
document.write和innerHTML的区别
document的作用是向页面写入文档流,会重绘整个页面。如果在输出之前页面已经有内容,那么在执行以后会删除之前的内容
而innerHTML将内容写入某个DOM节点,不会导致页面全部重绘
区别1:write是方法,而innerHTML是属性。前者会向页面输出文档流;后者表示相对应元素的内容。
区别2:重复write,会重复打印文档,重复n次,页面就会有n个"write";而innerHTML则会显示最后一次innerHTML的内容(反复刷新)。这里就可以解决昨晚的始终问题,用innerHTML来渲染页面,就可以保证实时刷新时间。
原型链
这个看的我头晕,总之就是一个类会根据prototype去原型对象中去寻找请求的属性或者方法,而如果prototype没有,则会去原型对象的对象空间中去找,如果没有就返回undefined。总之就是原型对象也是对象,也有自己的对象空间,同样是用__proto__去访问,这个不用细细理解。按照玄幻小说的说法就是,每个人以及他的同系血脉都有一个共同的本命空间来存放法器,然后本命空间自己也是有自己想法的,他自己也有个本命空间,这空间就没想法了,到头了。
这也就解释了为什么用原型方法、构造方法创造函数时候,出来的函数里面会有一个__proto__对象,然后这玩意打开里面还有个__proto__,懂了么,这就相当于萧炎打开自己的戒指然后又在戒指里打开药老的戒指一样。
p.s.3.5号更新
今天想了一下,感觉可以更加明确一点。 __proto__(隐式原型)呢,就像一个空间法术;prototype(原型)呢,就是老祖宗的百宝袋。ok现在开始解释!老祖宗的百宝袋里有各种法器,纵横江湖几十年,很无敌。然后某一天老祖宗决定开帮立牌,有了一大堆徒子徒孙,可这帮人不争气,出去丢老祖宗的脸,于是老祖宗就用一种叫“new”的法术,为这帮笨b开挂,然后老祖宗的徒子徒孙们人人都学会了一种叫“__proto__”的空间法术,这种法术最nb的是直接连通老祖宗的百宝袋!无论多远在哪,只要有需要就可以随时用!好了那么老祖宗的百宝袋“prototype”这帮笨b们可以随便用,那笨b们如果发现了一些奇珍异宝然后通过“__proto__”放入了百宝袋,那老祖宗那边呢?能用不?放肆!你们这帮笨b在外丢老祖宗的脸,还不让老祖宗用你们的东西了?吃里爬外的狗东西!
ok这就是老祖宗的故事,但你们以为这就完了么,江湖这么大老祖宗也不可能一直无敌,好在百宝袋兄弟争气,自己修炼出了神通!没错这个神通还是“__proto__”。。这里就要问了,百宝袋的空间法术连向哪里呢?神通之所以叫神通,就是因为与众不同,百宝袋老哥的空间法术,连向的是Object的原型!Object又是谁?如果不知道建议回炉重造,Object是所有对象的老大哥!是卡密!ok,百宝袋老哥修炼到能触碰Object的prototype了,那老祖宗终于可以不用担心,安心当咸鱼了,只需要每次在门派来新人(新实例)的时候,“new”给他一个“__proto__”就行了。
【以上纯属个人理解】
以下是今日正课学习内容:
闭包
说实话这个东西我在csdn的教程上发现,这是js高级语法之一。。然后我看了第一句:利用闭包延长局部变量的生命周期
What the fuck???????
ok,所以这里我直接没有再去参考w3c或者论坛的释义,这对萌新来讲也太痛苦了,我只写下我的理解:
闭包是什么?
闭包,就是一个封闭的环境,可以借助外部的变量,但外部无法调用闭包里定义的变量。这一点是由作用域的特性决定的。
闭包也是一种编码思想(技巧),一个函数可以访问另一个嵌套函数作用域的变量,父函数 > 子函数
为什么?
函数作用域的变量是私有的,减少变量冲突,可以暂存数据
怎么做?
书写嵌套关系的函数,返回子函数
子函数可以应用父函数的变量
观察以下代码,变量i就出现冲突
var i = 0;
i ++;
console.log(i);// 1
var i = 0;
i ++;
console.log(i);// 1
var i = 0;
i ++;
console.log(i);// 1
采用闭包解决上述的冲突
var add = function(){
var i = 0;
return function() {
i ++;
console.log(i);
}
}
var f1 = add();
f1();
f1();
f1();
console.log("f1-------");
var f2 = add();
f2();
f2();
f2();
f2();
f2();
console.log("f2-------");
var f3 = add();
f3();
f3();
f3();
this指向的改变方法
因为我在28号的笔记里写了this的概念,这里就只写改变方法
call 和 apply 和 bind
这些方法的作用是改变this的指向,只是书写方式不一样。
1. call 通过call改变this指向
先有以下代码:
定义对象A
var _this;
var objA = {
foo: function(){
_this = this;
console.log(this);
console.log(this.color);
}
}
var objB = {
color: "red"
}
这行代码 this.color是没有值的,是undefined,所以这里通过以下三种方法来使this变向:
1.objA.foo.call(objB);
2.objA.foo.apply(objB)
3.objA.foo.bind(objB)
这三行代码 改变了foo函数作用域this的指向,此处this指向objB
this.color是有值的,是 "red"
console.log(_this === objB);// true
当然这是最简单的东西,然后详细记录一下使用方法,不过其实就是传参的方法不一样,建议记apply,因为我看别人用的多
1.call
call 方法的调用者是函数
var objA = {
foo: function(msg,age){
console.log("颜色: ",this.color);
console.log("参数: ",msg,age);
}
}
var objB = {
color: "red"
}
objA.foo.call(objB,"hello world",20)
2.apply
apply 方法的调用者是函数,和call的传参不一样,它用的是数组
var objA = {
foo: function(msg,age){
console.log("颜色: ",this.color);
console.log("参数: ",msg,age);
}
}
var objB = {
color: "red"
}
通过apply改变this指向
objA.foo.apply(objB,["hello world",20]);
3.bind
bind 方法的调用者是函数
var objA = {
foo: function(msg,age){
console.log("颜色: ",this.color);
console.log("参数: ",msg,age);
}
}
var objB = {
color: "red"
}
通过bind改变this指向
objA.foo.bind(objB)("hello world",20);
总结:
改变函数作用域的this指向,有call、apply、bind这些方法
他们作用是一样的
书写方式不一样
为什么需要改变this指向?
一个对象可以拥有另一个对象的属性和方法 (继承性地一种体现)