关闭

细说javascript中的“指针”

1069人阅读 评论(0) 收藏 举报
分类:

故事背景

最近有朋友问我为什么我运行js代码会抛出如下异常

const Hoek = require('hoek');
^^^^^
SyntaxError: Use of const in strict mode.
} 

代码中有些乱码咱们就不细看,如果我们了解ES5的话,这是ES5所提供的严格模式, 解决方法可以是在文件或代码前加上”use strict”,如果不是很了解,可以参考文章Javascript 严格模式详解

很久没有遇到这类问题啦,所以就联想到当初遇到的一个大坑:关于js变量指向的内存地址和指针(有朋友会问,js中有指针的概念吗,js是有传址这一概念的-。-)。

结合栗子我们讲讲概念

刚开始学习js或者说ES6的时候,会遇到这样一个问题(默认你的环境已经能够正确兼容ES6)

const a = 1
a = 2
// 这里比较好理解,`const`声明的是一个常量,
// 如果要更改常量的值,编译过程肯定会抛出错误`TypeError: Assignment to constant variable`
// 告诉你声明的变量是一个常量,不可被改变

就简单的提一下const,顾名思义,const所声明的变量值不能被改变,那么在变量被声明的时候就应该被赋予了一个正确的值,可以是字符串,整型等(仔细想想,不赋予值,以后改不了了呀)

const a
// SyntaxError: Missing initializer in const declaration
// 变量没有被初始化

那么我们是不是就可以安然无忧的用const来声明我们的常量了呢,答案是可以的,但前提你应该知道这个

const obj = {}
obj.name = 'allen'

console.log(obj.name) // 'allen'

是的,对象的值被改变了,说好的const说声明的值不能被改变呢?(感觉受到了欺骗),所以这个时候我们就应该怀疑,const它实际所保证的是变量的值不能被改变的吗?我们再举一个例子

const obj = { name: 'allen' }
const _obj = obj

console.log(_obj) // { name: 'allen' }

obj.name = 'melo'

console.log(_obj) // { name: 'melo' }

走到这里我们能够猜测到,const所保证的应该是变量指向的内存地址不能够被改变,也就是保存的指针, 并不是保证变量的值不可以被改变,同理,当我们操作数组的时候,也会出现类似的情况,这就是引用传递(指针传递)

所以,在常量声明中,我们应该特别注意声明的变量如果是对象或数组类型,他实际上是可以被改变的

如果需要保证原本的对象本身不被改变,我们可以使用Object.freeze()来冻结所声明的对象变量

const obj = Object.freeze({})

obj.name = 'allen'

这一方法的解释是

Object.freeze() 方法可以冻结一个对象,冻结指的是不能向这个对象添加新的属性,不能修改其已有属性的值,不能删除已有属性,以及不能修改该对象已有属性的可枚举性、可配置性、可写性。也就是说,这个对象永远是不可变的。该方法返回被冻结的对象。

类似的问题,再举一个我们平常可能会遇到的坑

对于数组,我们有map()方法能够遍历原来的数组,改变原始数组的元素,并生成一个新的数组,通用的方法是

let array = [1, 2, 3]
let newArray = array.map(item => ++item)
console.log('newArray', newArray) // newArray: [2, 3, 4]

这是我们最常见的map()用法,但是请注意, 如果你操作的是一个对象数组, 那么原数组就可能被改变,原因就是我们之前提到的,实际改变的,是对象在被声明时所分配的内存地址的值,所以会发生指针没有被改变,但是指向的数据结构可以被改变

const array = [{ name: 'allen' }]
const _arr = array

console.log(_arr) // [{ name: 'allen' }]

array.map(item => item.name = 'melo')

console.log(_arr) // [{ name: 'melo' }]
console.log(array) // [{ name: 'melo' }]

因为array指针所指向的值被改变了,那么相应的变量所指向的那块内存地址所保存的指针也就被改变了,这也是一个比较经典的例子

结语

所以在实际的学习和开发的过程我们很有可能遇见这样的情况,那么这个时候我们就必须要留意指针所带给我们的便利性和风险,只要充分的理解了这一概念,这一类的错误我们就可以轻松避免或者排查出问题所在。

很久没有写博客了,最近工作任务比较繁重,没能坚持产出,新的一年必须得有所改变了,不忘初心

0
0
查看评论

node.js中遇到SyntaxError: Use of const in strict mode

用node.js的时候使用connect-mongo这个模块的时候出现SyntaxError: Use of const in strict mode这个错误,看了一下其中src/index.js的代码,使用了const、let、"use strict"这些高大上的东西,我的解决...
  • fd214333890
  • fd214333890
  • 2016-01-28 00:56
  • 18456

CNPM 遇到use strict的问题

/usr/lib/node_modules/cnpm/node_modules/npminstall/bin/install.js:5 const debug = require('debug')('npminstall:bin:install'); ^^^^^
  • u010570551
  • u010570551
  • 2016-09-09 14:55
  • 3792

koa+mongodb+pm2部署

koa+mongodb+pm2部署
  • uglynakedman
  • uglynakedman
  • 2017-11-20 17:31
  • 186

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside stric

我的是 node的版本太低造成的,我去官网上下载了个最新的版本,就没有这个问题了。 https://nodejs.org/zh-cn/download/current/
  • qwdafedv
  • qwdafedv
  • 2017-02-27 12:04
  • 2077

指针在javascript的使用方式

myweb var a=Object; //类似于C++中的 type *a var b=a; //类似于 type *b; b=a; a.cd="ylem"; //类似于 *a=&quo...
  • riyuedangkong1
  • riyuedangkong1
  • 2016-06-19 21:40
  • 186

(1)让你不再害怕指针--细说指针

指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。要搞清一个指针需要搞清指针的四方面的内容:指针的类型、指针所指向的类型、指针的值或者叫指针所指向的内存区、指针本身所占据的内存区。让我们分别说明。先声明几个指针放着做例子:例一:(1)int*ptr;(2)char
  • sunchaoenter
  • sunchaoenter
  • 2011-07-28 17:02
  • 1456

WebRTC AppRTC(一)环境配置详细步骤与坑总结

弄webrtc确实不是很好弄,目前仅调通了pc端的网页与手机端网页的视频。不过感觉还有些问题1、两者都必须要使用火狐浏览器2、感觉pc端摄像头拍出来的画面还可以,手机端稍微有点花3、进入房间接通后过一段时间才显示两个视频画面~~~~apprtc的demo还没有调通,问题出在turnserver,后面...
  • danfengw
  • danfengw
  • 2017-04-01 16:30
  • 7401

【Javascript】javascript 中的指针

C/C++语音中指针让很多人望而却步,Java中没有指针让很多人趋之若鹜。
  • cChenLiang
  • cChenLiang
  • 2017-06-01 10:48
  • 1070

JS里有指针么?

Are there pointers in javascript? No, JS doesn’t have pointers.Objects are passed around by passing a copy of a reference.
  • c__ilikeyouma
  • c__ilikeyouma
  • 2016-11-01 07:20
  • 1560
    个人资料
    • 访问:90972次
    • 积分:1225
    • 等级:
    • 排名:千里之外
    • 原创:34篇
    • 转载:4篇
    • 译文:0篇
    • 评论:20条
    博客专栏
    最新评论