常见的JavaScript易错知识点整理

域名2025-11-04 07:02:264

前言

本文是常见错知我学习JavaScript过程中收集与整理的一些易错知识点,将分别从变量作用域,识点类型比较,整理this指向,常见错知函数参数,识点闭包问题及对象拷贝与赋值这6个方面进行由浅入深的整理介绍和讲解,其中也涉及了一些ES6的常见错知知识点。

JavaScript知识点

1.变量作用域

var a = 1; function test() {     var a = 2;     console.log(a); // 2 } test(); 

上方的识点函数作用域中声明并赋值了a,且在console之上,整理所以遵循就近原则输出a等于2。常见错知

var a = 1;  function test2() {     console.log(a); // undefined     var a = 2; } test2(); 

上方的识点函数作用域中虽然声明并赋值了a,但位于console之下,整理a变量被提升,常见错知输出时已声明但尚未被赋值,识点所以输出“undefined”。整理

var a = 1; function test3() {     console.log(a); // 1     a = 2;  } test3(); 

上方的函数作用域中a被重新赋值,未被重新声明,且位于console之下,所以输出全局作用域中的a。

let b = 1; function test4() {     console.log(b); // b is not defined     let b = 2; } test4(); 

上方函数作用域中使用了ES6的let重新声明了变量b,而let不同于var其不存在变量提升的功能,所以输出报错“b is not defined”。

function test5() {     let a = 1;     {         let a = 2;     }     console.log(a); // 1 } test5(); 

上方的函数作用域中用let声明了a为1,源码下载并在块级作用域中声明了a为2,因为console并不在函数内的块级作用域中,所以输出1。

2.类型比较

var arr = [],     arr2 = [1]; console.log(arr === arr2); // false 

上方两个不同的数组比较,console为false。

var arr = [],     arr2 = []; console.log(arr === arr2); // false 

上方两个相同的数组比较,因为两个单独的数组永不相等,所以console为false。

var arr = [],     arr2 = {}; console.log(typeof(arr) === typeof(arr2)); // true 

上方利用typeof比较数组和对象,因为typeof获取NULL、数组、对象的类型都为object,所以console为true。

var arr = []; console.log(arr instanceof Object); // true console.log(arr instanceof Array); // true 

上方利用instanceof判断一个变量是否属于某个对象的实例,因为在JavaScript中数组也是对象的一种,所以两个console都为true。

3.this指向

var obj = {     name: xiaoming,     getName: function () {         return this.name     } }; console.log(obj.getName());  // xiaoming 

上方对象方法中的this指向对象本身,所以输出”xiaoming”。

var obj = {     myName: xiaoming,     getName: function () {         return this.myName     } }; var nameFn = obj.getName; console.log(nameFn()); // undefined 

上方将对象中的方法赋值给了一个变量,此时方法中的this也将不再指向obj对象,从而指向window对象,云服务器所以console为”undefined”。

var obj = {     myName: xiaoming,     getName: function () {         return this.myName     } }; 

var obj2 = {     myName: xiaohua  }; var nameFn = obj.getName; console.log(nameFn.apply(obj2)); // xiaohua 

上方同样将obj对象中的方法赋值给了变量nameFn,但是通过apply方法将this指向了obj2对象,所以最终console为’xiaohua’。

4.函数参数

function test6() {     console.log(arguments); // [1, 2] } test6(1, 2); 

上方利用函数中的arguments对象获取传入函数的参数数组,所以输出数组[1, 2]。

function test7 () {     return function () {         console.log(arguments); // 未执行到此,无输出     } } test7(1, 2); 

上方同样利用arguments获取参数,但因test7(1, 2)未执行return中的函数,所以无输出,若执行test7(1, 2)(3, 4)则会输出[3, 4]。

var args = [1, 2]; function test9() {     console.log(arguments); // [1, 2, 3, 4] } Array.prototype.push.call(args, 3, 4); test9(...args); 

上方利用Array.prototype.push.call()方法向args数组中插入了3和4,并利用ES6延展操作符(…)将数组展开并传入test9,所以console为[1, 2, 3, 4]。

5.闭包问题

var elem = document.getElementsByTagName(div); // 如果页面上有5个div for(var i = 0; i < elem.length; i++) {     elem[i].onclick = function () {         alert(i); // 总是5     }; } 

上方是一个很常见闭包问题,点击任何div弹出的值总是5,因为当你触发点击事件的时候i的值早已是5,可以用下面方式解决:

var elem = document.getElementsByTagName(div); // 如果页面上有5个div for(var i = 0; i < elem.length; i++) {     (function (w) {         elem[w].onclick = function () {             alert(w); // 依次为0,1,2,3,4         };     })(i); } 

在绑定点击事件外部封装一个立即执行函数,并将i传入该函数即可。

6.对象拷贝与赋值

var obj = {     name: xiaoming,     age: 23 }; var newObj = obj; newObj.name = xiaohua; console.log(obj.name); // xiaohua console.log(newObj.name); // xiaohua 

上方我们将obj对象赋值给了newObj对象,从而改变newObj的b2b供应网name属性,但是obj对象的name属性也被篡改,这是因为实际上newObj对象获得的只是一个内存地址,而不是真正 的拷贝,所以obj对象被篡改。

var obj2 = {     name: xiaoming,     age: 23 }; var newObj2 = Object.assign({}, obj2, {color: blue}); newObj2.name = xiaohua; console.log(obj2.name); // xiaoming console.log(newObj2.name); // xiaohua console.log(newObj2.color); // blue 

上方利用Object.assign()方法进行对象的深拷贝可以避免源对象被篡改的可能。因为Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。

var obj3 = {     name: xiaoming,     age: 23 }; var newObj3 = Object.create(obj3); newObj3.name = xiaohua; console.log(obj3.name); // xiaoming console.log(newObj3.name); // xiaohua 

我们也可以使用Object.create()方法进行对象的拷贝,Object.create()方法可以创建一个具有指定原型对象和属性的新对象。

结语

学习JavaScript是一个漫长的过程,不能一蹴而就。希望本文介绍的几点内容能够帮助学习JavaScript的同学更加深入的了解和掌握JavaScript的语法,少走弯路。

同时也欢迎大家关注我的微信公众号:前端呼啦圈(Love-FED),来这里聊点关于前端的事情。

来自——微信公众号:前端呼啦圈(Love-FED)

本文地址:http://www.bzuk.cn/html/312c34399344.html
版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

热门文章

全站热门

电脑开机总提示错误恢复(解决电脑开机错误的有效方法)

总所周知,Docky是Unix/Linux类系统中的轻量级应用启动器。我是 Lubuntu 和 Docky 的忠实粉丝,因为它们不需要占用我的所有系统资源,这样就可以同时运行更多应用。我在笔记本上使用Docky应用启动器,系统为Lubuntu 14.04.但是,假如你使用LXDE发行版,你也许肯定遇到过使用Docky时报混合的错误。看下面的截图。假如不开启混合功能,就不能使用Docky一些特别功能,如3D背景、自动隐藏。假如你想开启这些Docky的功能,那么你需要在你的LXDE系统中开启混合功能。就像这样,首先安装 xcompmgr包:sudo apt-get install xcompmgr然后,选择菜单(Menu) ->偏好(Preferences) ->LXSession默认程序(Default applications for LXSession)。选择自动开始(Autostart)选项卡。 在(+增加)+Add框中输入“@xcompmgr -n”不带引号。最后点击增加按钮。这样就搞定了。关掉LXSession配置窗口,注销或重启系统。之后,你就可以看见混合功能已经打开。这时,你就可以使用3D背景和隐藏功能,如自动隐藏(Auto-hide),Intellihide和窗口闪烁(Window dodge)等。搞定!干杯!

大多数的 Linux Distro 也将 IPv6 (Internet Protocol Version 6) 预设地开启,但有时实际上不需要 IPv6 支援,如要关闭 IPv6 可用以下方法: Debian / Ubuntu 1. 开启 /etc/modprobe.d/aliases 2. 里面有一行是 “alias net-pf-10 ipv6″ 3. 将以上一行用以下两行取代: alias net-pf-10 off alias ipv6 off Red Hat 1. 开启 /etc/modprobe.conf 2. 加入这一行: alias net-pf-10 off 更改以上档案后重新启动系统,这时 IPv6 便会关闭。我在 Ubuntu 上关闭了 IPv6 后,发觉 DNS 的效能改善了,那就是一般上网时要 resolve ip 时回应得更快。

Wireshark 是一个基于 GUI 的数据包捕获和嗅探工具。该工具被网络管理员普遍使用,网络安全工程师或开发人员对于各种任务的数据包级的网络分析是必需的,例如在网络故障,漏洞测试,应用程序调试,或逆向协议工程是必需的。 Wireshark 允许实时记录数据包,并通过便捷的图形用户界面浏览他们的协议首部和有效负荷。这是 Wireshark 的 UI,尤其是在 Ubuntu 桌面下运行时,当你向上或向下滚动分组列表视图时,或开始加载一个 pre-recorded 包转储文件时,有时会挂起或冻结,并出现以下错误。显然,这个错误是由 Wireshark 和叠加滚动条之间的一些不兼容造成的,在最新的 Ubuntu 桌面还没有被解决(例如,Ubuntu 15.04 的桌面)。一种避免 Wireshark 的 UI 卡死的办法就是 暂时禁用叠加滚动条。在 Wireshark 上有两种方法来禁用叠加滚动条,这取决于你在桌面上如何启动 Wireshark 的。命令行解决方法复制代码代码如下:复制代码代码如下:复制代码代码如下:复制代码代码如下:$ cp /usr/share/applications/wireshark.desktop ~/.local/share/applications/

电脑登QQ错误的解决方法(解决电脑登QQ出现错误的实用技巧)

自己加工电脑屏幕教程(DIY电脑屏幕定制,让你的显示更出色)

今天查了一下,squid对dns的支持是这样一个原理: 1、假如dns server发送域名时带有ttl,则以此ttl为准,一般dns server都会带有对ttl的支持,现在我用的dnsmasq默认ttl是0。 2、假如dns server没发送ttl(ttl=0),squid就以自己的配置positive_dns_ttl为准,这个配置默认是6小时。 3、原先squid里配置的一个negative_dns_ttl,证实是配错了,这个配置指的是squid在取不到域名(出错)的情况下会多久再去重取。 我原先的情况是positive_dns_ttl和dns server的ttl都没有配置而配置了negative_dns_ttl,这时squid以默认的positive_dns_ttl为准,即6小时,这个时间对web服务器来说太长了。当前我解决的办法是修改dns server的ttl为60 有些朋友可能是用bind来做的dns,bind可能默认的ttl并不是0,所以用positive_dns_ttl配置不起效的话,修改ttl值就好。 附:检测dns服务器ttl值的方法 在一台linux机器上,修改/etc/resolv.conf将dns指向到要测试的dns,然后执行 dig test.com 假如该dns能解析test.com,就会返回一系列数据,其中有一列指明了ttl值,一试即知。

Ubuntu是一个以桌面应用为主的Linux操作系统,是linux平台下很受欢迎的系统。Putty是Windows上常用的登录Linux的终端工具。登录终端如图系统内登录终端一样。默认情况下,ubuntu终端上显示的中文字符常常是乱码。下面就说下,如何解决Putty登录Ubuntu中文显示乱码问题。1、在使用putty连接登录Linux时,发现了终端下显示乱码,如下图所示。2、之后,在终端下输入echo $LANG $LANGUAGE,回测。之后即可看到en_US、UTF-8。这个信息说明该系统下支持这两种字符集。3、之后,选择标题,右击选择菜单中的“Change Settings”选项。4、之后,进入到putty的设置页面。同时,也可以直接双击putty运行程序,进入到设置页面。5、进入到设置页面之后,选择左侧点击【Window】下的“Translation”选项,之后在右侧会看到“Remote character set:”选项。6、通过下拉菜单,选择“UTF-8”字符集选项。7、之后,再次在终端下输入相应的指令,即可看到显示正常的中文编码了。8、最后,下次登录服务器只要双击putty.exe,然后在页面中输入IP以及端口(默认22即可),然后【Open】就可以连接ubuntu服务器了。连接服务器需要进行身份验证,输入系统的用户名以及密码。注意事项:中文乱码的解决也需要系统的支持,本经验验证是在ubuntu下进行的。

热门文章

友情链接

滇ICP备2023006006号-33