javascript

位置:IT落伍者 >> javascript >> 浏览文章

JavaScript中几个重要的属性


发布日期:2023年07月16日
 
JavaScript中几个重要的属性

this
this表示当前对象如果在全局作用范围内使用this则指代当前页面对象window  如果在函数中使用this则this指代什么是根据运行时此函数在什么对象上被调用  我们还可以使用apply和call两个全局方法来改变函数中this的具体指向
先看一个在全局作用范围内使用this的例子

代码如下:
<script type=>
consolelog( ===  window);
consolelog(windowalert === alert);
consolelog(parseInt(  ));
</script>


函数中的this是在运行时决定的而不是函数定义时如下

代码如下:
foo() {
consolelog(fruit);
}  
fruit = ;
foo();
pack = {
fruit:
foo: foo
};  
packfoo();


全局函数apply和call可以用来改变函数中this的指向如下

代码如下:
foo() {
consolelog(fruit);
}  
fruit = ;
pack = {
fruit:
};
fooapply(window);  
fooapply(pack);  


apply和call两个函数的作用相同唯一的区别是两个函数的参数定义不同  
因为在JavaScript中函数也是对象所以我们可以看到如下有趣的例子

代码如下:
foo() {
( === window) {  
consolelog();
}
}
fooboo = () {
( === foo) {  
consolelog();
} ( === window) {
consolelog();
}
};  
foo();
fooboo();
foobooapply(window);  


prototype
prototype本质上还是一个JavaScript对象  并且每个函数都有一个默认的prototype属性
如果这个函数被用在创建自定义对象的场景中我们称这个函数为构造函数 比如下面一个简单的场景

代码如下:
Person(name) {
name = name;
}  
Personprototype = {
getName: () {
name;
}
}
zhang =  Person();
consolelog(zhanggetName());  


作为类比我们考虑下JavaScript中的数据类型   字符串(String)数字(Number)数组(Array)对象(Object)日期(Date)等  我们有理由相信在JavaScript内部这些类型都是作为构造函数来实现的比如
Array() {
}
arr =  Array( );
arr = [ ];  
同时对数组操作的很多方法(比如concatjoinpush)应该也是在prototype属性中定义的  
实际上JavaScript所有的固有数据类型都具有只读的prototype属性(这是可以理解的因为如果修改了这些类型的prototype属性则哪些预定义的方法就消失了)  但是我们可以向其中添加自己的扩展方法
Arrayprototypemin = () {
min = [];
( i = ; i  < length; i++) {
([i] < min) {
min = [i];
}
}
min;  
};
consolelog([ ]min());  
注意这里有一个陷阱向Array的原型中添加扩展方法后当使用forin循环数组时这个扩展方法也会被循环出来  
下面的代码说明这一点(假设已经向Array的原型中扩展了min方法)
arr = [ ];
total =  ;
( i arr) {
total += parseInt(arr[i] );
}  
consolelog(total);
解决方法也很简单
arr = [ ];
total = ;  
( i arr) {
(arrhasOwnProperty(i)) {
total += parseInt(arr[i] );  
}
}
consolelog(total);
constructor  
constructor始终指向创建当前对象的构造函数比如下面例子

代码如下:
arr = [ ];  
consolelog(arrconstructor === Array);
Foo = () { };  
consolelog(Fooconstructor === Function);
obj = Foo();  
consolelog(objconstructor === Foo);  
consolelog(objconstructorconstructor === Function);  


但是当constructor遇到prototype时有趣的事情就发生了  
我们知道每个函数都有一个默认的属性prototype而这个prototype的constructor默认指向这个函数如下例所示

代码如下:
Person(name) {
name = name;
};  
PersonprototypegetName = () {
name;
};
p = Person();  
consolelog(pconstructor === Person);  
consolelog(Personprototypeconstructor === Person);  
consolelog(pconstructorprototypeconstructor === Person);  


当时当我们重新定义函数的prototype时(注意和上例的区别这里不是修改而是覆盖)  constructor的行为就有点奇怪了如下示例

代码如下:
Person(name) {
name = name;
};  
Personprototype = {
getName: () {
name;
}
};
p =  Person();
consolelog(pconstructor === Person);  
consolelog(Personprototypeconstructor === Person);  
consolelog(pconstructorprototypeconstructor === Person);  


为什么呢?
原来是因为覆盖Personprototype时等价于进行如下代码操作

代码如下:
Personprototype = Object({
getName: ()  {
name;
}
});  


而constructor始终指向创建自身的构造函数所以此时Personprototypeconstructor ===  Object即是

代码如下:
Person(name) {
name = name;
};  
Personprototype = {
getName: () {
name;
}
};
p =  Person();
consolelog(pconstructor === Object);  
consolelog(Personprototypeconstructor === Object);  
consolelog(pconstructorprototypeconstructor === Object);  


怎么修正这种问题呢?方法也很简单重新覆盖Personprototypeconstructor即可

代码如下:
Person(name) {
name = name;
};  
Personprototype = Object({
getName: () {
name;
}
});  
Personprototypeconstructor = Person;
p = Person();  
consolelog(pconstructor === Person);  
consolelog(Personprototypeconstructor === Person);  
consolelog(pconstructorprototypeconstructor === Person);               

上一篇:javascript实现文字图片上下滚动的具体实例

下一篇:JS日期和时间选择控件升级版