JavaScript秘密花园 - hasOwnProperty,Functions,this

JavaScript 秘密花园.pdf 立即下载

hasOwnProperty

为了判断一个对象是否包含自定义属性而不是原型链上的属性, 我们需要使用继承自 Object.prototype 的 hasOwnProperty 方法。

注意: 通过判断一个属性是否 undefined 是不够的。 因为一个属性可能确实存在,只不过它的值被设置为 undefined。

hasOwnProperty 是JavaScript中唯一一个处理属性但是不需要查找原型链的方法。

?
1
2
3
4
5
6
7
8
9
// 修改Object.prototype
Object.prototype.bar = 1;
var foo = {goo: undefined};
 
foo.bar; // 1
'bar' in foo; // true
 
foo.hasOwnProperty( 'bar' ); // false
foo.hasOwnProperty( 'goo' ); // true

只有 hasOwnProperty 可以给出正确和期望的结果,这在遍历对象的属性时会很有用。 没有其它方法可以用来排除原型链上的属性,而不是定义在对象自身上的属性。

hasOwnProperty 作为属性(hasOwnProperty as a property)

JavaScript 不会保护 hasOwnProperty 被非法占用,因此如果一个对象碰巧存在这个属性, 就需要使用外部的 hasOwnProperty 函数来获取正确的结果。

?
1
2
3
4
5
6
7
8
9
10
11
var foo = {
     hasOwnProperty: function () {
         return false ;
     },
     bar: 'Here be dragons'
};
 
foo.hasOwnProperty( 'bar' ); // 总是返回 false
 
// 使用其它对象的 hasOwnProperty,并将其上下为设置为foo
{}.hasOwnProperty.call(foo, 'bar' ); // true

结论(In conclusion)

当检查对象上某个属性是否存在时,hasOwnProperty 是唯一可用的方法。 同时在使用 for in loop 遍历对象时,推荐总是使用 hasOwnProperty 方法, 这将会避免原型对象扩展带来的干扰。

函数(Functions)

函数是JavaScript中的一等对象,这意味着可以把函数像其它值一样传递。 一个常见的用法是把匿名函数作为回调函数传递对异步函数中。

函数声明(The function declaration)

?
1
function foo() {}

上面的方法会在执行前被 解析(hoisted),因此它存在于当前上下文的任意一个地方, 即使在函数定义体的上面被调用也是对的。

?
1
2
foo(); // 正常运行,因为foo在代码运行前已经被创建
function foo() {}

函数赋值表达式(The function expression)

?
1
var foo = function () {};

这个例子把一个匿名的函数赋值给变量 foo。

?
1
2
3
foo; // 'undefined'
foo(); // 出错:TypeError
var foo = function () {};

由于 var 定义了一个声明语句,对变量 foo 的解析是在代码运行之前,因此 foo 变量在代码运行时已经被定义过了。

但是由于赋值语句只在运行时执行,因此在相应代码执行之前, foo 的值缺省为 undefined。

命名函数的赋值表达式(Named function expression)

另外一个特殊的情况是将命名函数赋值给一个变量。

?
1
2
3
4
var foo = function bar() {
     bar(); // 正常运行
}
bar(); // 出错:ReferenceError

bar 函数声明外是不可见的,这是因为我们已经把函数赋值给了 foo; 然而在 bar 内部依然可见。这是由于 JavaScript 的 命名处理 所致, 函数名在函数内总是可见的。

this 的工作原理(How this works)

JavaScript 有一套完全不同于其它语言的对 this 的处理机制。 在五种不同的情况下 ,this 指向的各不相同。

全局范围内(The global scope)

?
1
this ;

当在全部范围内使用 this,它将会指向全局对象。 (译者注:浏览器中运行的JavaScript脚本,这个全局对象是 window)

函数调用(Calling a function)

?
1
foo();

这里 this 也会指向全局对象。

ES5 注意: 在严格模式下(strict mode),不存在全局变量。 这种情况下 this 将会是 undefined。 (译者注:ES5指的是ECMAScript 5,是2009-12发布的最新的 JavaScript 版本。)

方法调用(Calling a method)

?
1
test.foo();

这个例子中,this 指向 test 对象。

调用构造函数(Calling a constructor)

?
1
new foo();

如果函数倾向于和 new 关键词一块使用,则我们称这个函数是 构造函数。 在函数内部,this 指向新创建的对象。

显式的设置 this(Explicit setting of this)

?
1
2
3
4
5
function foo(a, b, c) {}
 
var bar = {};
foo.apply(bar, [1, 2, 3]); // 数组将会被扩展,如下所示
foo.call(bar, 1, 2, 3); // 传递到foo的参数是:a = 1, b = 2, c = 3

当使用 Function.prototype 上的 call 或者 apply 方法时,函数内的 this 将会被 显式设置为函数调用的第一个参数。

因此函数调用的规则在上例中已经不适用了,在foo 函数内 this 被设置成了 bar。

注意: 在对象的字面声明语法中,this 不能用来指向对象本身。 因此 var obj = {me: this} 中的 me 不会指向 obj,因为 this 只可能出现在上述的五种情况中。 (译者注:这个例子中,如果是在浏览器中运行,obj.me等于window对象。)

常见误解(Common pitfalls)

尽管大部分的情况都说的过去,不过第一个规则(译者注:这里指的应该是第二个规则,也就是直接调用函数时,this 指向全局对象) 被认为是JavaScript语言另一个错误设计的地方,因为它从来就没有实际的用途。

?
1
2
3
4
5
6
Foo.method = function () {
     function test() {
         // this 将会被设置为全局对象(译者注:浏览器环境中也就是 window 对象)
     }
     test();
}

一个常见的误解是 test 中的 this 将会指向 Foo 对象,实际上不是这样子的。

为了在 test 中获取对 Foo 对象的引用,我们需要在 method 函数内部创建一个局部变量指向 Foo 对象。

?
1
2
3
4
5
6
7
Foo.method = function () {
     var that = this ;
     function test() {
         // 使用 that 来指向 Foo 对象
     }
     test();
}

that 只是我们随意起的名字,不过这个名字被广泛的用来指向外部的 this 对象。 在 closures 一节,我们可以看到 that 可以作为参数传递。

方法的赋值表达式(Assigning methods)

另一个看起来奇怪的地方是函数别名,也就是将一个方法赋值给一个变量。

?
1
2
var test = someObject.methodTest;
test();

上例中,test 就像一个普通的函数被调用;因此,函数内的 this 将不再被指向到 someObject 对象。

虽然 this 的晚绑定特性似乎并不友好,但是这确实基于原型继承赖以生存的土壤。

?
1
2
3
4
5
6
7
function Foo() {}
Foo.prototype.method = function () {};
 
function Bar() {}
Bar.prototype = Foo.prototype;
 
new Bar().method();

当 method 被调用时,this 将会指向 Bar 的实例对象。

JavaScript 秘密花园 JavaScript 秘密花园是一个不断更新,主要关心 JavaScript 一些古怪用法的文档。 对于如何避免常见的错误,难以发现的问题,以及性能问题和不好的实践给出建议, 初学者可以籍此深入了解 JavaScript 的语言特性,0分下载 立即下载

相关推荐

使用Eggjs做服务端获取微信小程序云开发数据库的access_token

最近自己想写了一个微信小程序,恰巧里面有个云开发,恰巧里面有个数据库,那懒人的我,就直接用云开发里面的数据库了,做测试或者正式也好,对于刚开始来说,免费的配额是够用的。 后来想到在小程序云开发上面的数据怎么看才方便?刚好微信小程序有一个服务端API,那就方便很多了,那就直接敲个服务端来获取云开发上数据库的数据出来到自己的后台上面,那以后管理起来也方便很多。 看了一下服务端api之后,发现有三个重要...

kalenE992的博客 1705

《JavaScript 秘密花园》—一些奇奇怪怪的知识

读《JavaScript 秘密花园》,根据自己知识缺漏摘抄部分内容,以及实际代码执行结果

qq_40029828的博客 1327

【AMD显卡在WIndow10/11部署带GPU支持的深度学习环境(Pytorch-DirectML篇)】

这篇是之前Tensorflow-DirectML的姊妹篇,如果对TF感兴趣的可以搜索我的博文。 首先我们丢一个官网地址,但是官网那个会误导新人如果你按那个操作的话。 https://docs.microsoft.com/en-us/windows/ai/directml/gpu-pytorch-windows 这里用我的方法操作: 首先声明一下,因为我的显卡是AMD RX6600,不带XT(性能和RTX3060 12G版本半斤八两),所以目前没有最新的WSL2驱动,如果有了的话欢迎告知我,所以我这里就.

weixin_44029053的博客 2万+

javascript秘密花园

大家请参考http://www.jb51.net/onlineread/JavaScript-Garden-CN/,真的很好

wudiazu的博客 1097

VMware vCenter 6.7证书过期急救指南:从503报错到完美修复的全流程

本文详细解析了VMware vCenter 6.7因STS证书过期导致503报错的根本原因,并提供了一套从诊断到修复的完整实战流程。内容包括使用checksts.py脚本检测STS证书状态,通过fixsts.sh脚本更新证书,以及利用Certificate-Manager全面重置所有过期证书,帮助管理员快速恢复服务并避免常见陷阱。

weixin_29234239的博客 772

qcom bypass node介绍

介绍qcom bypass node,以及如何让其生效

haodada1226的博客 2045

JavaScript 的秘密花园

1、对象: JS中所有的变量都是对象,

咸鱼的星空 1326

高通Sensor Tuning实战:手把手教你用Chromatix生成并打包bin文件(附避坑指南)

本文详细介绍了高通Sensor Tuning的全流程实战,从Chromatix配置到Bin文件加载验证。通过手把手教程,帮助开发者掌握Chromatix工具链的使用,避免常见配置错误,提升调试效率。特别针对kalama等新一代平台,提供经过验证的解决方案和避坑指南。

ios99的博客 483

JavaScript - scope, namespace, constructor, equality and comparisons

JavaScript Garden - 原文 作用域与命名空间 尽管 JavaScript 支持一对花括号创建的代码段,但是并不支持块级作用域; 而仅仅支持函数作用域。 function test() { // 一个作用域for(var i = 0; i < 10; i++) { // 不是一个作用域// count} console.log(i); // 10} ...

iteye_6378的博客 234

最新版IAR9.40和注册工具

IAR最新版的IDE在编译速度和代码提示等各个方面上都有很大提升,软件这个东西果然还是越新越好。之前的时候,IAR v9系列网上很多人都说能用,但是又没有把 IAR v9系列的注册方法写的很清楚,导致我一直都用注册老版本v8的方法去注册v9。结果注册后都会提示。

xue_nuo的博客 4万+

uniapp 全局弹窗

功能详解1.有的组件需要全局调用,不想要在一个页面里面一个个引入,现在就需要写入到全局中,直接全局触发。2.通过 $rechargePop就能全局触发 充值的弹窗实现步骤一、先把组件封装好,如 rechargePop组件位置 components/RechargePop/index.vue ,就定义一个methods open方法就可以 二、在同级别路径下定义一个 index.js 三、引入到main.js 四、全局调用this.$rechargePop(); 就能弹出那个弹窗

weixin_42066070的博客 657

[翻译]JavaScript秘密花园 - hasOwnProperty,Functions,this

JavaScript Garden - 原文 JavaScript Garden - 中文翻译 hasOwnProperty 为了判断一个对象是否包含自定义属性而不是原型链上的属性, 我们需要使用继承自 Object.prototype 的 hasOwnProperty 方法。 注意: 通过判断一个属性是否 undefined 是不够的。 因为一个属性可能确实存在,只不

三生石上 629

2026.1.9:最新VSCode集成claude插件完美解决方案,跳过登录界面,使用国内Kimi K2进行计费

本文介绍了如何安装配置Claude插件并连接Kimi K2 API的详细步骤:1)搜索安装Claude插件;2)进入设置关闭登录提示;3)在settings.json中添加API配置,包括ANTHROPIC_AUTH_TOKEN(需替换为Kimi API Key)和ANTHROPIC_BASE_URL;4)通过Kimi官网获取API Key。完成配置后即可正常使用该插件。文中配有完整的操作截图指引。

拥抱具身智能,昇腾Ascend C 8724

《Javascript秘密花园》学习笔记(终)

实践了许多代码后,回头再看《Javascript秘密花园》,又有一些收获,与诸君分享 数组 typeof运算符 Value Class Type ------------------------------------- "foo" String string new String("f...

weixin_34252686的博客 329

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

”JavaScript 秘密花园“ 学习笔记 :

JavaScript秘密花园学习笔记

罗曼蒂克在消亡 379

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

《JavaScript 秘密花园》

恰巧今天是传统民间重要的节日之一——七夕节:被大家挂在嘴上最多的一句话便是:有对象了吗?这不……这样的话,那咱就先给new出一个对象吧:var boyfriend = new Object();然后再往其中增加属性,比如:他的名字叫Jay;1.对象:①增加属性boyfriend['name']='Jay'; ②访问属性(两种方式:点操作符或者中括号操作符)boyfriend.name;//"Jay...

weixin_34174105的博客 299

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

javascript 秘密花园 http://bonsaiden.github.com/JavaScript-Garden/zh/

enzhrufipltr #topHide Menu 简介 关于作者贡献者许可 对象 对象使用和属性原型hasOwnProperty 函数for in 循环 函数 函数声明与表达式this 的工作原理闭包和引用arg

WolfMan_SunnyWolf的专栏 1万+

JavaScript 秘密花园 http://bonsaiden.github.com/JavaScript-Garden/zh/

简介JavaScript 秘密花园是一个不断更新,主要关心 JavaScript 一些古怪用法的文档。 对于如何避免常见的错误,难以发现的问题,以及性能问题和不好的实践给出建议, 初学者可以籍此深入了解 JavaScript 的语言特性。 JavaScript 秘密花园不是用来教你 JavaScript。为了更好的理解这篇文章的内容, 你需要事先学习 JavaScript 的基础知识。...

dianzongfan5428的博客 3962

《JavaScript秘密花园》— 笔记

前言本文是笔者阅读了《JavaScript秘密花园》之后的一些总结,主要是一些平常容易忽略的小知识点。数字的字面值如何当做对象使用2.toString(); // 出错:SyntaxError, JS解析器将数字与点操作符视为一体 // 解决办法 2..toString(); // 以小数形式表示 2 .toString(); // 中间留空 (2).toString(); // 利用圆括号的优...

weixin_34202952的博客 442
上一篇: JavaScript秘密花园 - Type Casting,undefined,eval,setTimeout,Auto Semicolon Insertion
下一篇: web.py 0.3 新手指南
迷渡
迷渡 领域专家: 前端开发技术领域 领域专家: 前端开发技术领域
博客等级 码龄19年 2405粉丝 124原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值