发表于: 2019-12-24 18:49:37

1 1295


今天的收获:

    let声明
var a= [ ]
for(let i = 0 ; i < 10; i++){
 a[i] = function (){
console.log(i)
}
}
当i是几时 就会输出几 , 因为let 声明相对于的是一个块及作用域,这个i只对本次的循环有效果,
所以每一次循环的i其实都是一个新的变量,所以最后输出的是6。
如果在for循环里面用var 声明 i 的话循环出来的新的i会覆盖掉旧的,其实就是形成了一个闭包。
let声明不存在变量提升
console.log(a)
let a = 0 ;
这样操作输出的会是一个报错,不是未定义,var 声明输出的将会是一个未定义,不会报错,所以说let不存在变量提升。
变量提升:在运行JS脚本的时候就会把所有的提升,只是说明这个变量现在存在了,但是,不会给这个提升的变量赋值,变量提升。
那么let 不存在这样的提升。let声明的变量,只有在let这一条执行后才可以调用。
let的暂时性死区
var a = '3'function (){a='2' ;let a;}
在一个代码块内使用let声明了一个变量之后 这个变量就绑定在了这个作用域上面,不在会有作用域链这种情况出现,所以a 会输出一个报错
当然,let声明只会绑定使用let声明的变量,使用let声明的变量将不存在寻找外部变量的说法。
 var tmp = 123;
   var  a  = '2'
   if (true) {
       console.log(a)
       tmp = 'abc'; // ReferenceError
       let tmp;
       console.log(tmp)
   }
tmp输出的报错,a输出的2 这就很明显的可以看出来了,let绑定了tmp这个变量,只在当前作用域内寻找变量,而a没有被let声明所以a会沿着作用域链寻找a这个变量。
var tmp = new Date(); function f() {  console.log(tmp);  if (false) {    var tmp = "hello world";  } } f();
f输出的为undefined  在全局声明一个tmp 这个变量就已经存在了,然后在函数内部又声明了一个tmp 这就会出现一个问题,函数内部的tmp也会有一个变量提升,那么变量提升是不会赋值的,所以这个tmp是undefined就相当于是这段代码
var tmp = new Date(); function f() {
var tmp  console.log(tmp);  if (false) {    tmp = "hello world";  } } f();
相当于tmp没有赋值就打印了一下tmp 所以输出undefined。
不允许重复声明
function () {  let a = 10;  var a = 1; }
function () {  let a = 10;  let a = 1; }
这样操作都是会报错的,因为在同一个代码块内是不允许重复声明一个变量的,奥,只是对于let来说,用var 声明的话是可以在同一个代码块内声明的 重复声明也行,但是let 会报错。{}一个花括号相当于一个代码块,
function f1() {
   let a = 1;
   console.log(a);
   {
       let a = 2
       console.log(a)
   }
}
f1()
因为一个花括号相当于一个代码块,所以这样写的话就相当于,俩个let声明的变量,在俩个作用域内,所以不会报错。
   let a = 1;
function f1() {
   {
       console.log(a)
   }
}
let声明一个全局变量的情况下,作用域内也是可以使用到的,不会报错。
const 声明的是一个常量,不可改变,
const a = 2   a = 3   因为const声明的是常量所以,在给const声明的常量赋值的时候会报错,
const和let一样不可重复声明,当一个作用域内有这个变量再使用const声明这个变量时就会报错。一样也是不存在变量提升的,在声明之前调用会报错,不报undefined。
const声明的是一个指向的地址,保证的是指向的地址不变,但是,当你改变这个地址内的值的时候,const是会执行的。什么 意思呐
const a = {}// 声明const a  是一个对象,那么不会改变的就是这个const是一个对象,你可以改变的是,a.name =  '小星星',这样操作你没有改变这个a 的地址,只是改变了这个地址内的值,所以const 声明不可改变的只是这个地址,a = {'小星星'} 这样的操作是改变了a的地址,因为a指向的不在{}而是指向了  {'小星星'}。
const  a = {}
a.name = '小星星' // 可以执行,也可以读到这个值,
a = {'小星星'} //报错, 因为你这样写改变了 a 指向的地址。
在同一个作用域内不可以出现使用 var 和 let 声明的同一个变量如果出现var a  let a  let就会报错a 已经存在,声明过了。


                                  函数的拓展
function foo(x = 5) {  let x = 1; // error  const x = 2; // error }
在函数foo的参数里面x 已经声明过了所以let 和const 再次声明 x 的时候会报错。参数的变量的默认已经声明过的变量。
function log(x, y = 'World') {  console.log(x, y); } log('Hello') // Hello World log('Hello', 'China') // Hello China log('Hello', '') // Hello
函数log 的x 是一个变量 x 没有默认值,  y也是一个变量y的默认值是World,当你不需要给y传实参的时候那么y就是World,当你传了实参的时候那么y的值就是这个实参,
function foo({x, y = 5}) {  console.log(x, y); } foo({}) // undefined, 5 foo({x: 1}) // 1, 5 foo({x: 1, y: 2}) // 1, 2 foo() // TypeError: Cannot read property 'x' of undefined
默认值可以与变量结构配合起来使用,x一个没有赋值的变量,y有默认值, 那么就可以用变量结构,只给x 传值,变量必须与属性同命。
function m1({x = 0, y = 0} = {}) {  return [x, y]; } function m2({x, y} = { x: 0, y: 0 }) {  return [x, y]; }
写法1 函数m1 的参数是有默认值的,当不传实参的时候x和y便会输出0  就算传一个空的参数进去也不会覆盖掉本身的默认值,
写法2 不传参数的时候也是有默认的值的,会输出0 ,  但是,当传了空的参数的时候便会输出undefined, 空的参数为{}
function foo(x = 5, y = 6) {  console.log(x, y); } foo(undefined, null) // 5 null
当函数的参数有默认值的时候,传入undefined就会出发默认值的执行,null则没有这个效果,null是一个对象,相当于一个空值。
function f(x, y, z=5) {
   return [x, y, z];
}
console.log(f(1,2)) //  1,2,5
在函数的参数末尾的参数有默认值的时候则可以省略给这个参数传参数,但是,当这个有默认值的参数 不在末尾时则不可以省略,如果省略了给这个参数传参会报错。是在想要省略给这个参数传参,则只能把这个有默认值的参数后面的也省略传参。
function f(x, y=5, z) {
   return [x, y, z];
}

console.log(f(1,null,2)) // 输出的是 1,null,2  null改为undefined则输出 1,5,2。

                                        对象:ES6
var birth = '2000/01/01'; var Person = {  name: '张三',  //等同于birth: birth  birth,  // 等同于hello: function ()...  hello() { console.log('我的名字是', this.name); } };
属性与方法的简写,birth 是一个变量,当你写进一个对象的时候那么 他就是属于这个对象的一个属性了,属性名为变量名,属性值为变量的值,简写定义方法  hello(){}相当于 hello:function(){}。。
let propKey = 'foo';
let obj = {
   [propKey]: true,
   ['a' + 'bc']: 123
};
console.log(obj.foo);
console.log(propKey)
对象obj使用一个变量来作为属性名的时候那么在调用这个属性的时候,这个属性名其实是这个变量的值。即 obj.propKey  这样会报错。propKey未定义,  调用的时候需要obj,foo 这样就会看到foo是true
// let obj = {
//     ['h' + 'ello']() {
//         return 'hi';
//     }
// };
// console.log('my name is'+  obj.hello())
这里说一个我以前没懂的地方, 就是return 回来的值到底有什么用,return回来的值是可以直接在需要用的地方调用的。 比如上面这个console



返回列表 返回列表
评论

    分享到