今天在Codewars刷题,碰到一个7kyu
(这个等级,学过一点js的人,都会做)等级的题目,题目很简单:
求累加和,并对异常情况进行特殊处理。看着非常简单,事实上并不难。我的第一次代码:
// ?????
var SequenceSum = (function () {
function SequenceSum () { }
var sum = 0
var str = ''
SequenceSum.showSequence = function (count) {
for (let i = 0; i < count; i++) {
str += `${i}+`
sum += i
}
sum += count
if (count < 0) return `${count}<0`;
if (count == 0) return `${count}=0`;
return `${str}${count} = ${sum}`
};
return SequenceSum;
})();
测试结果:
但是在自己本地跑代码, 整个结果是没有错误的。看了上面的结果,错误的输出都有0+1+2+3+4+5+
这段,然而这段代码正好是我在循环中所定义的,看来在测试的时候,对于第一次循环时所产生的结果并没有进行CG。
JavaScript是弱类型语言,可以不需要声明变量而直接使用。这样虽然简单但不易发现变量名方面的错误,所以不建议这样做。通常的做法是在使用JavaScript变量前先声明变量。目前,JavaScript变量声明方式有3种,分别是使用var、let和const关键字声明。其中,使用var声明变量,是ECMAScript6版本以前一直使用的方式,由于这种方式声明的变量在某些情况下会导致一些问题,因而在ECMAScript6版本中增加了使用let和const两种方式声明变量。
老生常谈,我就不多写了。
方式一:var 变量名;
方式二:var 变量名1,变量名2,…,变量名n;
方式三:var 变量名1 = 值1,变量名2 = 值2,…,变量名n = 值n;
方式一:let 变量名;
方式二:let 变量名1,变量名2,…,变量名n;
方式三:let 变量名1=值1,变量名2=值2,…,变量名n=值n;
const 变量名 = 值;
需要特别注意的是:使用const声明变量时,必须给变量赋初值,且该值在整个代码的运行过程中不能被修改。另外,变量也不能重复多次声明。这些要求任何一点没满足都会报错。
if (true) {
let num = 3;
const msg = "How are you?";
}
alert(num); //num为块级变量,离开判断块后无效,所以报:Uncaught ReferenceError
alert(msg); //msg为块级变量,离开判断块后无效,所以报:Uncaught ReferenceError
for (let i = 0; i < 9; i ++ ) {
var j = i;
}
alert(i); //i为块级变量,离开循环块后无效,所以报:Uncaught ReferenceError
alert(j); //j为全局变量,离开循环块后仍有效,所以运行正常,输出结果:8
var gv1 = "JavaScript";
let gv2 = "JS";
const number = "10000";
var gv1 = "VBcript"; //correct
let gv2 = "JScript"; //Uncaught SyntaxError:Identifier'gv2'has already been declared
const number = "20000";//Uncaught SyntaxError:Identifier'number'has already been declared
alert(gv1);
alert(gv2);
alert(number);
var msg = "JavaScript";
var p = 123;
if(true){
console.log("块内输出msg:" + msg);//Uncaught ReferenceError: Cannot access 'msg' before initialization
console.log("块内输出p:" + p);//UVM79:5 Uncaught ReferenceError: Cannot access 'p' before initialization
let msg = "JScript";
const p = 456;
}
console.log("块外输出msg:" + msg); //③
console.log("块外输出p:" + p); //④
上面报的错误:VM79:5 Uncaught ReferenceError: Cannot access 'msg' before initialization
,其实就是之前的:Uncaught ReferenceError:msg is not defined
。
这个错误原因是因为①和②处代码处在“暂时性死区”中,由此也可见,块变量不会受外部变量影响。
上面写到的区别,其实注重于块级作用域的问题,而我做的题目就是因为块级作用域从而导致了内存重复读取或者没有清楚块内内存的问题。修改代码如下:
var SequenceSum = (function () {
function SequenceSum () { }
SequenceSum.showSequence = function (count) {
let sum = 0
let str = ''
for (let i = 0; i < count; i++) {
str += `${i}+`
sum += i
}
sum += count
if (count < 0) return `${count}<0`;
if (count == 0) return `${count}=0`;
return `${str}${count} = ${sum}`
};
return SequenceSum;
})();