1.★this—问题提出
请大家先看一段代码:
function Person(){
}
var p1=new Person();
p1.name=”顺平”;
p1.age=60;
window. alert (p1.name+” “+p1.age);
var p2=new Person();
window.alert(p2.name); //这里会输出什么?(undefined)
在实际编程中,我们可能有这样的需求,当我们 创建一个对象后 ,就希望该 对象自动的拥有某些属性
(比如:当我们创建一个Person对象后,就希望该对象自动拥有name和阿哥属性,这又怎么办?)
2.解决之道:使用this
js虚拟 机会给每一个 对象分配this , 代表当前对象 。
坦白的讲,要明白this(我的)不是件容易的事情,给大家打一个比方(上帝造人小故事)
function Person(){
this.name=”abc”
this.age=90;
}
var p1=new Person();
var p2=new Person();
P1.name=”顺平”;
window.alert(p1.name+” “+p2.name);
改变p1的name不会影响到p2
两个对象空间
//输出 abc abc
3.★内存图分析
4.★★私有与公开
补充:在定义类(原型对象)中,var和this
① 私有属性 var
② 公开属性 this
③ 私有方法 function
④ 公开方法(js中一般都是公开方法)this
demo1.html
<html>
<head>
<script language=”javascript”>
function Person(){
var name=”abc”;
1)私有属性
① 如果这样去使用 name这个 属性是私有 的
② 私有属性不能单独访问,可以通过授权的公开方法进行访问
2)公开属性
this.name2 =”abc2″;
① this.name2 表示name2这个 属性是公开 的
② 公开属性和公开方法都可以使用对象.属性/方法进行调用
3)公开方法
this.show=function(){
① 这个就是Person的一个 公开方法
② 如果你一定要 访问私有属性 ,则需要定义一个 公开方法 ( 特权方法 )
记忆下面:
③ 公开方法可以访问私有和公开属性
④ 公开属性,必须+this;私有不用加
window.alert(name); //name属性是私有的
}
4)私有方法
function show2(){
① 这个是 私有方法 , 只能 在 Person类 中使用
② 如果想在 外部使用show2 ,可以在 this.show 中调用,即在 公开方法 中调用私有方法
③ 一般来讲,javascript中大部分方法都是公开的
}
}
var p1=new Person();
//这样调用name属性, 私有 的会报 undefined
window.alert(p1.name);
//输出 abc2
//name2属性是公开的
window.alert(p1.name2);
//如果要访问私有属性name,就要在类中定义一个公开的方法,比如定义一个show方法
p1.show();
</script>
</head>
<body><body>
</html>
5.★★进一步加深理解this:
① 因为这个和前面的概念 存在冲突 ,所以定下这样一条规则
② 直接定义的是 全局变量 和全局成员方法,属于顶层对象window,可以直接调用
③ 全局的==公开的
1)案例 1
demo2.html
<html>
<head>
<script language=”javascript”>
function test1(){
alert(this.v);
}
var v=90;
window.test1();
输出90
① 什么都不写, 默认 是 window 对象,window 可以省略
② 输出什么 等价于== test1(); 即:alert(“ok”); <==> window.alert(“ok”);
③ 哪个对象实例调用this所在的函数,那么this就代表哪个对象实例
④ window.test1(); this就是window,进去了以后,调test1,如果test1里面有this,那个这个this就是调用者window,这个this有没有v呢,在外面定义了一个v=90。 window 对象是 全局对象, 意味着公开 。
window.alert(v); //输出v
window.alert(window.v) //同样输出的v,和上面的一样的。
window对象是全局对象,在上面的test1函数中alert(this.v);,
不就是等同于alert(window.v);吗,这样就容易理解了
★★★★
应该这么去想:test1这个函数,从面向对象的角度看,它应该是属于某个对象的,它就是属于window的。
alert(“ok”);
window.alert(“ok”);这两个是一个意思,alert这个函数默认就是window对象。
我们过去调用函数是这样写
test1(); 这个就是前面没有写window而已,它和下面的是一样的。
window.test1();
//什么叫当前对象是this呢
2)案例2
function Person(){
this.abc=function(){
window.alert(this.v); //这里的this就是p,谁调用this,this就是谁
} }
var p=new Person();
p.v=”hello”; //动态的
p.abc(); //p调用abc,p就是里面的this,而this确实有v这个属性,则hello就被输出了
3)内存分析图(案例2中的)
★★★★
在上图中,刚开始创建的时候堆0x1234中什么都没有,然后p.v=”hello”;,
就在堆0x1234中放入了数据,紧接着p.abc();
调用函数,调用函数就开辟新栈了,在新栈里面this就被传进去了,此时这个this实际上就等价于p,p是对象,实际上传了地址,this就指向了ox1234,this.v,this是个地址就到堆中寻找,则hello就被输出了。
在内存图中分析,就能理解的透彻了。谁调用这个函数,谁就是这个this
4)javascript中的 HTML DOM window对象
window对象是javascript层级中的 顶级对象 。
window对象代表一个 浏览器窗口 或 一个框架
window对象会在<body>或<frameset>每次出现时被自动创建
window对象表示一个浏览器窗口或一个框架。在客户端javascript中,window对象是全局对象,所有的表达式都在当前的环境中计算。也就是说,要引用当前窗口根本不需要特殊的语法,可以把那个窗口的属性作为全局变量来使用。例如,可以只写 document ,而不必写window.document。
同样,可以把当前窗口对象的方法当做函数来使用,如可只写alert(),而不必写window.alert()。
★★★★★记住一句话:
哪个对象实例调用this所在的函数,那么this就代表哪个对象实例。
6.★ this-注意事项
① this不能在类定义的外部使用, 只能 在 类定义 的 方法 中使用。
② 在类定义的 外部 , 调用者 就变成 window 了
window.alert(this.v);
在类定义的外部这样使用,此时的this指的是window了,就变成另外一个对象了,它并会把p.v的hello输出,因为在类的外部这个this已经指的是window了