标签:es6 const log let var console foo
一, ECMAScript和javascript的关系
ECMAScript是一个语法核心标准,javascript是语法的一种体现 。
二, es5的严格模式
1, 严格模式:
其实就是在一定程度上把语法规定的更标准,为了规范代码的标准性
2, 原因:
消除javascript 一些语法的不合理,不严谨,减少一些怪异行为
消除代码中的一些不安全的地方,保证代码的运行安全环境
提高编译效率,增加运行速度
为了将来的javascript的标准做准备
3, 使用方式:
将 use strict
放在所有代码的第一行,则整个脚本就处于一种严格编译的环境
如果这行不在整个代码块的首行,没有效果(非严格模式)
4, 使用范围:
全局范围
"use strict"; // es5的严格模式启动
a = 10;
console.log(a); // a is not define
for循环内的严格模式
"use strict";
for (i = 0; i < 5; i++) {
console.log(i);
}
console.log(i);
自执行函数
var a = 10
;(function(){
"use strict";
console.log(10);
})()
局部范围
function fn(){
"use strict"; // es5的严格模式启动
b = 10;
console.log(b); // b is not defined
}
fn()
5, 失效的情况:
如果严格模式之前有代码,严格会失效,有空格,分号都不行,但是注释没问题
b = 20;
"use strict";
a = 10;
console.log(a);
6, 如果使用了严格模式。会影响arguments
"use strict";
function fn(a){
arguments[0] = 2;
console.log(a);
console.log(arguments[0]);
}
fn(1);
// 变异
"use strict";
function fn(a){
arguments[0] = 2;
// 当使用alert的时候,严格模式失效
alert(arguments[0]);
}
fn(1);
7, eval()函数计算javascript字符串的,并把字符串当做一个脚本执行
如果参数是一个表达式,eval()函数执行表达式,如果参数是javascript的语句,eval()函数执行这个语句
console.log(eval("var a=10"));
eval("var a=10;console.log(a)");
console.log(eval("1+2")); // 3
console.log(eval("{b:2}"));
console.log(eval("({b:2})"));
eval("mytest()");
function mytest() {
console.log(1);
}
// 严格模式
"use strict";
var eval = 10;
console.log(eval);
var obj = {}
obj.eval=10;
obj.a = eval;
function fn(eval){
}
8, 严格模式删除系统内置属性会报错
"use strict";
/* console.log(Object.prototype); // __proto__
console.log(Function.prototype); */
// 内置属性
delete Object.prototype;
9, JSON格式的数据
JSON.parse() :把字符串格式的数据转换成json对象格式的数据
JSON.stringify():把json格式的数据转换为字符串格式的数据
var arr = [1,2,3];
console.log(typeof arr);
console.log(JSON.stringify(arr));
console.log(typeof JSON.stringify(arr));
console.log('-------');
var arr1 = '[1,2,3]';
console.log(typeof arr1);
console.log(JSON.parse(arr1));
console.log(typeof JSON.parse(arr1));
// 注意:属性名和属性值全部要使用引号引起来
var json = '{"name":"zhangsan"}'
10, Object()扩展
创建一个对象
基于一个对象,创建一个新的对象,并可以对新队形的属性进行描述(操作)
语法:Object.create(person,decrtion);
person:原有的对象
decrtion:属性描述 value:属性值
writable:属性是否可以修改新的属性,默认值是false,不可以修改
configurable:是否可以删除新的属性,默认值是false,不可以删除
ennumerable:是否可以枚举(遍历)默认值是false,不可以枚举(遍历)
创建一个对象:
var person = {
name:'张三',
age:20,
}
var me = Object.create(person);
me.name = '李四';
me.age = 30;
console.log(me);
操作属性
var me = Object.create(person, {
sex: {
value: '男',
writable:true, // 可以更改属性
configurable:true,//可以删除
enumerable:true,// 可以遍历(枚举)
},
sex1: {
value: '男',
}
})
// me.sex = '女';
delete me.sex;
// console.log(me.sex);
for(var attr in me){
console.log(attr);
}
Object.defineProperties(object,descriptors)
这个方法直接在一个对象上定义新的属性或者修改现有的属性,并返回该duixaing
object:定义或修改的属性的对象
get:作为该属性的getter函数,如果没有getter结果为undefined,函数返回值将被作为属性的值
set:作为该属性的setter函数,如果没有setter结果为undefined,函数返回值将被作为属性的值
var stus = {
scores:[
{
name:'张三1',score:65,
},
{
name:'张三2',score:65,
},
{
name:'张三3',score:65,
},
{
name:'张三4',score:65,
},
{
name:'张三5',score:65,
}
]
}
Object.defineProperties(stus,{
total:{
get:function(){
// 声明一个变量
var t = 0;
for(var i = 0; i<this.scores.length;i++){
t += this.scores[i].score;
}
return t;
},
enumerable:true, // 可以遍历
}
})
console.log(stus.total);
三, es6简介
1, let基本用法
es6新增了let命令,用来声明变量,他的用法类似var,但是声明的变量,只在let命令坐在的代码块内生效
{
let a = 10;
var b = 20;
}
console.log(a); // is not defined
console.log(b);
// let声明的变量只能在声明的当前的作用域内被访问
for循环特别适合使用let
for (let i = 0; i < 5; i++) {
console.log(i);
}
console.log(i); // is not defined
2, 使用let不存在变量提升
var a = undefined
console.log(a); // undefined
var a = 10;
console.log(b);
let b = 20; // 'b' before initialization
3, 暂时性死区
只要块级作用域内存在let命令,它声明的变量就绑定这个区域,在在受外部影响
var temp = 123; // 全局变量
if (true) {
temp = '123';
let temp; //'temp' before initialization
}
4, 比较隐秘的死区域
// 比较隐秘的死区域
function fn(x = y, y = 2) {
return [x, y]; // 'y' before initialization
}
fn();
// 正常
function fn(x = 2,y = x){
return [x, y];
}
fn();
5, 不允许重复声明
let b = 10;
let b = 30;
console.log(b); // 报错 不会覆盖
// 参数和变量重名
function fn(a){// a = 1;
let a;
}
fn(1);
四, 块级作用域
1, 为什么需要块级作用域
第一种场景
var tmp = new Date();
function f(){
console.log(tmp); // 变量提升
if(false){
var tmp = 'hello world';
}
}
f();
第二种场景,用来计数的循环变量泄露为全局变量
var s = 'hello';
for (var i = 0; i < 5; i++) {
console.log(i);
}
console.log(i); // 5 数据泄露
es6里面允许作用域的任意层嵌套
{{
{{{{
let a = 10
}}}}
}}
es6里面在内层块级作用域可以声明和外层的块级作用域同名的变量
{
{
let a = 10;
{
let a = 20;
console.log(a);
}
console.log(a);
}
}
在es6里面,块级作用域内声明的函数,建议或者说是最好使用字面量的方式声明函数
if(true){
let a = function(){
}
}
if语句在严格模式下
"use strict"; // 全错
if(true)
let a = 10;
if(true)
function fn(){}
2, const 基本用法
const声明一个只读的常量,一旦声明,常量的值就不能在改变
不可变指的是指向值的地址不可变,而不是值不可变
for (const i = 0; i < 5; i++) {
console.log(i);
}
const obj = {
name: 'lisi',
age: 20
}
3, var let const 之间的区别
1、var有变量提升 let和const没有变量提升
2、var没有块级作用域,let和const有块级作用域
3、let和const指向的值和地址
let a = 10;
a = 20; //
console.log(a);
const b = 10;
b = 20;
console.log(b);
const实际上保证的,并不是边量的值不得改动,而是变量的那个内存地址所保存的数据不得改动。
但对于复杂数据类型来说,变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总时指向另一个固定的地址)。
五, 解构赋值
es6允许按照一定的模式,将数组或对象中的数据提取出来,赋值给变量,这个过程叫做解构赋值。
1, 数组的解构赋值
let [a, b, c, d] = [1, 2, 3, 4]; //
console.log(a);
其他列子
let [a, b, c, d] = [1, 2, 3, 4]; //
console.log(a);
let [foo,[[bar],baz]] = [1,[[2],3]]
console.log(bar);
let [, , third] = ['foo','bar','baz'];
console.log(third);
let [head,...tail] = [1,2,3,4];
console.log(head); // 1
console.log(tail); // [2, 3, 4]
如果解构不成功,值为undefined
let [foo,foo1] = [,2];
console.log(foo); // undefined
另一种情况就是不完全解构,等号左边的模式,只匹配第一部分等号右边的数组,这种情况,结构依然可以成功
let [x, y] = [1, 2, 3];
console.log(x, y);
let [a, [b], d] = [1, [2, 3], 4];
console.log(a, b, d);
解构的时候,等号右边不是数组,报错
let [foo] = false;
对于set结构,也可以使用数组解构赋值
let [x,y,z] = new Set(['a','b','c']);
console.log(typeof x);
数组解构赋值允许指定默认值
let [foo = true] = [];
console.log(foo);
let [x,y='b'] = ['a'];
console.log(x,y);
es6内部使用严格相等运算符(===
)判断一个位置是否有值,所以只有当一个数组成员严格等于undefined
,默认值才生效
let [x = 1] = [undefined];
console.log(x);
// 默认值是null会直接赋值
let [y = 2] = [null];
console.log(y);
2, 对象解构赋值
解构赋值不仅仅可以用于数组,也可以用于对象
对象的解构赋值
let {foo,bar} = {foo:'a',bar:'b'};
console.log(foo);
对象的解构赋值和数组的解构赋值不一样,数组的元素是依次排列的,变量的值有位置决定,而对象的属性没有次序,变量必须与属性同名,才能取到值
let {baz} = {foo:'aaa',bar:'bbb'};
console.log(baz); //undefined
对象的结构赋值,可以很方便的将现有的对象的方法,赋值给某一个变量
const { log } = console;
log('hello'); //
如果变量名和属性名不一致,必须这么写
// 如果变量名和属性名不一致,必须这么写
let { foo: baz } = { foo: 'aaa', bar: 'bbb' };
// console.log(baz);
// 相等
let { foo: foo, bar: bar } = { foo: 'aaa', bar: 'bbb' }
console.log(bar);
与数组一样,对象解构也可以用于嵌套结构的对象
let obj = {
p: [
'hello',
{
y: 'world'
}
]
}
let { p: [x, { y }] } = obj;
console.log(x, y);
注意:这种情况下 p 是模式,不是变量,不会被赋值,如果 p 作为也要作为变量赋值
let obj = {
p: [
'hello',
{
y: 'world'
}
]
}
let {p, p: [x, { y }] } = obj;
console.log(x, y);
console.log(p);
对象也可以指定默认值
const { x = 3} = {};
console.log(x);
let {x,y=5} = {x:1};
console.log(x,y);
es6内部使用严格相等运算符(===
)判断一个位置是否有值,所以只有当一个对象成员严格等于undefined
,默认值才生效
var {x = 3} = {undefined};
console.log(x);
var {x = 3} = {x:null};
console.log(x);
如果将一个已经声明的变量用于解构赋值,使用的时候,必须得非常小心
let x;
{x} = {x : 1};
console.log(x);
// 正确方法
let x;
({x} = {x : 1});
console.log(x);
3, 函数参数的解构赋值
函数的参数也可以解构赋值
function add([x, y]) {
return x + y;
}
console.log(add([1, 2]));
[[1, 2], [3, 4]].map(([a, b]) => console.log(a + b));
参数也可以使用默认值
function add({ x = 0, y = 0 } = {}) {
return [x, y];
}
console.log(add());
console.log(add({ x: 3, y: 8 }));
// 另一种写法
function move({ x, y } = { x: 0, y: 0 }) {
return [x, y];
}
console.log(move({ x: 3, y: 9 }));
模板字符串
for (var attr = 0; attr < json.length; attr++) {
var cur = json[attr]
ul.innerHTML = `<li>
<a href="${cur.url}">${cur.title}</a>
</li>`;
}
六, 对象的扩展
es6允许在大括号里面,直接写入变量和函数,作为对象的属性和方法,这么写更简洁
const foo = 'bar';
const baz = {foo};
console.log(baz);
// 等同于
const baz = {foo:foo}
另外一种写法
function f(x, y) {
return { x, y }
}
// 等同于
function f(x, y) {
return { x: x, y: y }
}
console.log(f(1,2)); // {x: 1, y: 2}
属性名表达式
Javascript定义对象的属性,有两种方法
// 方法一
obj.foo = true;
// 方法二
obj['a' + 'bc'] = 123;
es6里面允许属性名以表达式的形式存在,但是必须使用方括号[]
let propKey = 'foo';
let obj = {
[propKey]:true,
['h' + 'ello']:123
}
console.log(obj.hello);
另一种方式
let lastWorld = 'last world';
const a = {
'first world':'hello',
[lastWorld]:'world'
}
console.log(a['first world']);
console.log(a[lastWorld]);
表达式定义方法名
let obj = {
['h'+'ello'](){
return 'h';
}
}
console.log( obj.hello());
注意:属性名表达式和简洁写法,不能同时使用,会报错
// 报错
const foo = 'bar';
const bar = 'abc';
const baz = { [foo] };
// 正确
const foo = 'bar';
const baz = { [foo]: 'abc' }
console.log(baz); // {baz:'abc'}
属性名表达式是一个对象,默认情况下回将对象转为字符串[object],这个要小心
const keyA = { a: 1 };
const keyB = { b: 2 };
const myObject = {
keyA:'valueA',
keyB:'valueB'
}
console.log(myObject);
七, 函数扩展
es6新增了一种新的函数:ArrayFunction(箭头函数)
es6允许使用“箭头(=>)”定义函数
var f = v => v; // f:函数名 v:参数(形参)
// 等同于
var f = function(v){
return v;
}
如果箭头函数不需要参数或者需要多个参数,就使用()
代表参数部分
// 没有参数
var f = () => {return 5};
console.log(f());
// 定义参数
var sum = (num1, num2) => num1 + num2;
sum(10, 20); // 30
当代码有两条语句或者多余两条语句的时候,代码块要放在{}
var sum = (num1, num2) =>{return num1 + num2};
sum(10, 20); // 30
由于大括号{}
之间的代码,会被解释为代码块,所以,如果箭头函数直接返回一个对象,必须在对象的外面加上括号,否则会报错
// 报错
let getTemp = (id) => {
id: id,
name: 'Temp',
};
// 正确
let getTemp = (id) => ({
id: id,
name: 'Temp',
});
console.log(getTemp('box'));
// 值是undefined
let foo = () => {a:1};
console.log(foo()); //undefined
标签:es6,const,log,let,var,console,foo 来源: https://www.cnblogs.com/bnzw/p/13880604.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。