这是我参与更文挑战的第9天,活动详情查看:
更文挑战
with
with是一个语法。 在代码执行的时候,会改变作用域
with (target) {
console.log(a) // 如果target中存在a 属性, 那么会优先输出a, 如果没有回沿着词法作用域一直往上查 找
}
举例:
正常模式下:
// 定义对象
var obj = {
a: 1,
b: 2
}
var a = 10;
var b = 20;
// 使用with
with (obj) {
// 此时obj 中 存在a 和 b 那么会优先输出 obj中的a和b
console.log(a);
console.log(b);
// 此时obj中存在a属性, 所以优先改变的是Obj中的a
a = 111;
// obj中没有c 所以会将c添加在全局中
c = 123;
}
结果:
严格模式下:
// 开启严格模式
"use strict"
// 定义对象
var obj = {
a: 1,
b: 2
}
var a = 10;
var b = 20;
// 使用with
with (obj) {
// 此时obj 中 存在a 和 b 那么会优先输出 obj中的a和b
console.log(a);
console.log(b);
// 此时obj中存在a属性, 所以优先改变的是Obj中的a
a = 111;
// obj中没有c 所以会将c添加在全局中
c = 123;
}
结果:
变量名称
在正常模式下,在一个对象中定义属性可是用名的
严格模式下,不会报错, 只是浏览器检测不出来
正常模式下:
// 定义对象
var obj = {
a: 1,
a: 2
}
console.log(obj.a);
输出:
严格模式下:
// 开启严格模式
"use strict"
// 定义对象
var obj = {
a: 1,
a: 2
}
console.log(obj.a);
输出:
注:没有区别, 不是严格模式没有开启, 只是浏览器没有实现
全局函数作用域
在全局函数作用域的this指向window, 会污染全局作用域
在严格模式下全局函数作用域中的this 变为undefined, 就可以避免对全局作用域的污染
在正常模式下:
// 定义函数
function fun() {
var b = 10;
console.log(b);
// 全局函数作用域
console.log(this);
// 添加属性
this.color = "red";
}
fun();
结果:
严格模式下:
// 开启严格模式
"use strict"
// 定义函数
function fun() {
var b = 10;
console.log(b);
// 全局函数作用域
console.log(this);
// 添加属性
this.color = "red";
}
fun();
结果:
函数参数
正常模式下,定义函数的参数可以是同名的, 但是后面会覆盖前面的
严格模式下不允许定义同名参数
正常模式下:
// 定义函数
function fun(color, color) {
console.log(color);
}
fun("red", "blue");
输出:
严格模式下:
// 开启严格模式
"use strict"
// 定义函数
function fun(color, color) {
console.log(color);
}
fun("red", "blue");
结果:
对象的拓展
特性
对象是什么,我们用属性来描述
属性是什么, 我们用特性来描述
特性是用来描述属性的
Object.defineProperty
作用: 用于设置单个属性的特性
使用方式:
Object.defineProperty(obj, property, options)
obj: 要设置的对象
property: 设置的属性
options: 描述特性对象
举例:
在没有设置特性之前:
// Es5
var obj = {
color: "red",
width: 100
}
//使用for循环
for (var i in obj) {
console.log(i);
}
结果:
在设置了特性之后:
// Es5
var obj = {
color: "red",
width: 100
}
// 定义特性
Object.defineProperty(obj, "color", {
// 修改可枚举性
enumerable: false
})
//使用for循环
for (var i in obj) {
console.log(i);
}
结果:
特性--配置值
使用方式:
Object.defineProperty(obj, property, {
value:“”
})
举例:
// ES5
var obj = {
color: "red"
}
// 定义特性
Object.defineProperty(obj, "color", {
// 配置值
value: "green"
})
console.log(obj);
注:如果一个对象中,存在该属性,此时描述特性对象中的其他属性默认都是true
如果一个对象中,没有属性而是通过定义特性的方式添加的属性,那么描述特性对象中的其他属性默认全部是false
特性--可修改性
使用方式:
Object.defineProperty(obj, property, {
writable: false // 将可修改性设为false
})
举例:
// ES5
var obj = {
color: "red"
}
// 定义特性
Object.defineProperty(obj, "color", {
// 不可写入
// writable: false
writable: true
})
// 尝试修改obj.color
obj.color = "blue";
console.log(obj);
设置特性之后将不可修改:
特性--可枚举性
使用方式:
Object.defineProperty(obj, property, {
enumerable: false // 将可枚举性改为false
})
举例:
// ES5
var obj = {
color: "red",
width: 200
}
// 默认情况下可以被枚举的
// for (var i in obj) {
// console.log(i, obj[i]);
// }
// 定义特性
Object.defineProperty(obj, "color", {
// 修改可枚举性
enumerable: false
// enumerable: true
})
// 再次使用for循环
for (var i in obj) {
console.log(i, obj[i]);
}
结果:
特性--可配置性
使用方式:
Object.defineProperty(obj, property, {
configurable: false // 将可配置性改为false
})
举例:
// ES5
var obj = {
color: "red",
width: 200
}
// 定义特性
Object.defineProperty(obj, "color", {
value: "blue",
// 不可写入
writable: false,
// 不可配置
configurable: false
})
// 再次配置
Object.defineProperty(obj, "color", {
value: "pink",
// 不可写入
writable: true,
})
// 尝试修改obj.color
obj.color = "green";
console.log(obj);
修改可配置性为false之后:
特性方法
get用来获取属性值的
没有参数
返回值就是要获取的属性值
作用域是当前对象
千万不要在该方法中获取属性值,否则会递归死循环
通常我们获取该属性的一个备用值
set用来设置值的
参数就是要设置的值
没有返回值
作用域是当前对象
千万不要在该方法中,设置属性值
通常我们设置该属性的一个备用属性
举例:
// 定义对象
var obj = {
color: "red"
}
// 设置特性
// 一旦设置了特性方法(set, get),当obj.color; 就会触发get函数, 当obj.color = xx; 就会触发set函数
Object.defineProperty(obj, "color", {
// 取值器
get: function() {
console.log(111, this, arguments);
// 千万不要在方法中获取该属性
// return this.color;
// 获取该属性的备用值
return this._color;
},
// 赋值器
set: function(value) {
console.log(222, this, arguments);
// 千万不要设置该属性值
// this.color = value;
// 设置该属性的备用值
this._color = value;
}
})
obj.color = "blue";
console.log(obj.color);
设置多个属性特性
使用方式:
Object.defineProperties(obj, options)
obj: 要设置的对象
options: 特性对象
key: 特性属性
value: 属性特性对象
设置特性属性和方法
举例:
// 定义color和num的特性
Object.defineProperties(obj, {
color: {
// 值
value: "blue",
// 不可写入
writable: false,
// 不可枚举
enumerable: false
},
num: {
// 取值器
get: function() {
return this._num;
},
set: function(value) {
this._num = value;
},
// 不可枚举
enumerable: false,
// 一旦设置了特性方法(set, get), 将无法再次配置writable, value
// 不可写入
// writable: false,
// 配置值
// value: 300
}
})
原型方法
ES5为原型拓展了几个方法
isPrototypeOf
原型对象的方法
用于判断原型对象是否是参数对象的原型
参数就是实例化对象
在查找的时候,会查找整个原型链
// 获取所有div
var obj = document.getElementsByTagName("div");
// 定义数组
var arr = [];
// 数组的原型是哪个对象的原型呢?
console.log(Array.prototype.isPrototypeOf(obj));
console.log(Array.prototype.isPrototypeOf(arr));
// 在查找原型的时候,会查找整个原型链
console.log(Object.prototype.isPrototypeOf(obj));
console.log(Object.prototype.isPrototypeOf(arr));
getPrototypeOf
是对象的静态方法
用于获取原型对象
在ES5之前,获取原型对象的方式,__proto__
来获取原型对象, 以__开头,在ES5中不推荐使用, 所以提供了getPrototypeOf方法
// 获取arr的原型对象
console.log(arr.__proto__);
console.log(Object.getPrototypeOf(arr));
console.log(arr.__proto__ === Object.getPrototypeOf(arr));
输出:
setPrototypeOf
作用: 设置某一对象的原型对象(可以是一个对象也可以是null)
使用方式:
Object.setPrototypeOf(obj, prototype)
obj: 将被设置原型的对象
prototype: 新的原型对象 (可以是一个对象也可以是null)
举例:
// 设置arr新的原型对象
// 会修改整个原型链
// Object.setPrototypeOf(arr, null);
Object.setPrototypeOf(arr, {"name": "laowang"});
console.log(Object.getPrototypeOf(arr));
对象的拓展
Object.preventExtensions
作用: 用于取消对象的可拓展性
举例:
// 定义对象
var obj = {
a: 1
}
// 对象默认是可以拓展了
obj.b = 2;
// 取消对象的可拓展性
Object.preventExtensions(obj);
// 尝试添加属性
obj.c = 3;
console.log(obj);
// 结果,添加失败, 原因就是取消了对象的可拓展性
总结: 当取消了对象的可拓展性, 仍然可以修改属性值, 删除属性 查看对象是否取消可拓展性: Object.isExtensible(obj) 返回 true | false
// 查看对象的可拓展性是否被取消
console.log(Object.isExtensible(obj));
Object.seal
作用: 用于封闭对象
举例:
// 定义对象
var obj = {
a: 1
}
// 封闭对象
Object.seal(obj);
总结: 封闭之后 对象可以被访问, 不能拓展, 不能删除属性, 可以修改属性值
查看对象是否被封闭: Object.isSelead(obj) 返回 true | false
Object.freeze
作用: 冻结对象
举例:
// 定义对象
var obj = {
a: 1
}
// 冻结对象
Object.freeze(obj);
// 添加属性
obj.b = 2;
// 修改属性值
obj.a = 111;
// 删除属性
delete obj.a
console.log(obj);
输出:
总结: 当对象冻结以后: 不能添加属性, 不能修改属性值, 不能删除属性 查看对象是否冻结: Object.isFrozen(obj) 返回 true | false
对象创建的新方式
使用方式: Object.create(prorotype, options)
接受两个参数:
第一个参数是一个对象(可以设置为null)
该对象是Object.create创建出来的原型对象
第二个参数是一个对象(可省略)
该对象是Object.create创建出来的特性对象
举例:
// 创建原型对象
var prototype = {
say: function() {
console.log("say");
},
sayHello: function() {
console.log("sayHello");
},
sayNihao: function() {
console.log("sayNihao");
}
}
// 特性对象
var options = {
color: {
// 值
value: "red",
// 不可写入
writable: false
},
num: {
// 值
value: 200,
// 不可枚举
enumerable: false
}
}
var obj = Object.create(prototype, options);
输出: