一 作用域题
1. 变量、函数声明提升
2. 按顺序执行
3. 关于 this
-> 调用函数前面没有加 xx.fn() 都指向window
-> 匿名函数指向 window 对象
var 没有块状作用域的概念/ let、const
var foo = 1;
function bar() {
if (!foo) {
var foo = 10;
}
// alert(foo); // 10
}
bar();
- 先提升函数,再提升变量声明,此时foo未赋值,故在函数中被赋值为10.
- 所以在函数内部打印是10.
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
// alert(a); // 1
- 简单类型值作为参数,函数内部的变化不会影响到传入的变量
- 引用类型值作为参数,函数内部的变化会影响到传入的变量
- 所以在外部打印还是1.
二 对象属性新写法
- 1.如果对象的属性名与代表属性值的变量名一致,绑定属性的时候可以简写为属性名。
var age = 12;
var tel = "1234567";
var user = {
name: "李白",
// age: age
age,
tel
}
console.log(user); // user={name:"李白",age:12,tel:"1234567"}
- 2.给对象绑定函数属性的时候,可以将 : function 去掉.
var obj = {
say: function(){
console.log("say");
},
run(){
console.log("run");
}
}
obj.say();
obj.run();
三 对象数据属性
-
1.configurable: 对象属性是否可配置特性,是否可被删除
**2.enumerable:**对象属性能否被遍历处理
以上两个属性可作为访问器属性与get()、set()搭配使用 -
**3.writable:**对象属性能否被重新赋值
-4.value: 对象属性的值
只作为数据属性不与访问器属性混合使用 -
Object.defineProperty(obj, propertyName, descriptor)
- obj,propertyName 要处理的对象和属性。
- descriptor 要应用的属性描述符。
-( 描述符在 use strict 的情况下会申明语法错误) -
defineProperties
Object.defineProperties() 方法用来一次定义多个属性,这个方法接受两个对象参数:
Object.defineProperties(user, {
name: { value: “John”, writable: false },
surname: { value: “Smith”, writable: false }, // … });
- getOwnPropertyNames
Object.getOwnPropertyNames(obj) 可以得到 obj 所有的属性,无论它是否可枚举。
var obj = {
name: “李白”,
age: 24 } Object.defineProperty(obj, “tel”, {
value: “123456” })
Object.getOwnPropertyNames(obj) // [“name”, “age”, “tel”]
- Object.keys
-获取对象所有可枚举的属性
var obj = {
name: “李白”,
age: 24 }
Object.defineProperty(obj, “tel”, {
value: “123456” }) console.log(Object.keys(obj)); // [“name”, “age”]
- Object.getOwnPropertyDescriptor(obj, “属性”)
获取对象的属性描述符 - 如果对象的属性是通过definexx申明的,它的四个数据属性描述符的默认值为 false、undefined。
var obj = {
name: "张三",
age: 13
}
Object.defineProperty(obj, "tel", {
// 通过 defineProperty 定义的属性,三个数据配置项均为false
value: "123456"
})
console.log(Object.getOwnPropertyDescriptor(obj, "tel"));
console.log(Object.getOwnPropertyDescriptor(obj, "age"));
四 访问器属性
get: 函数,读取属性,返回值为读取值
set: 函数,设置属性调用此函数,参数为设置的值对象上有 get set 描述属性 obj = { get 属性名(){ 返回值为读取此属性的值 } set 属性名(设置的值){ 设置此属性的值 } } 在对象中以 _ 开头的属性表示不可访问更改属性(保护属性), 需要自行设置,加_只是为了告诉别人。
var user = {
lastName: "李",
firstName: "太白",
get fullName(){
//读取属性时调用此函数
return this.lastName + this.firstName;
},
set fullName(v){
// 设置属性时调用此函数
this.lastName = v[0];
this.firstName = v.slice(1);
}
}
console.log(user.fullName); // 读取调用get结果:李太白
user.fullName = "苏东坡"; // 设置
console.log(user); //设置后调用结果: 苏东坡
var book = {
// 原价 50
_price: 50,
cut: .9
}
Object.defineProperty(book, "price", {
configurable: false,
enumerable: true,
get() {
return this._price * this.cut;
}
})
console.log("9折", book.price); //45
book.cut = .6;
console.log("6折", book.price); // 30
五 双向绑定
举例:
<input type="text" placeholder="输入用户名" value="李白">
var data = {
name: ""
}
// 从外边获取值
var ipt = document.querySelector("input");
Object.defineProperty(data, "name", {
get(){
return ipt.value;
},
set(v){
$("input").val(v);
}
})
// 读取data.name 返回input.value
console.log(data.name); // 李白
// 设置data.name input.value也更改 5秒后变成苏轼
setTimeout(function (){
data.name = "苏轼";
}, 5000)
题目:
给任意 input 元素添加 v-module 属性,在 data 中添加相应属性,并实现双向数据绑定,生成的属性不可枚举。
name改为"李白",data中添加name属性,值为"李白"
<input type="text"> placeholder="请输入姓名" value="" v-module="name">
<input type="text"> placeholder="请输入年龄" value="" v-module="age">
<input type="text"> placeholder="请输入年龄" value="">
<script>
var data = { };
</script>
var data = {};
// 获取所有带 v-module 属性的input标签
var ipts = document.querySelectorAll("input[v-module]");
for(let i = 0; i < ipts.length; i ++){
var key = ipts[i].getAttribute("v-module");
console.log(key);
Object.defineProperties(data, {
[key]: {
enumerable: false,
get(){
return ipts[i].value;
},
set(v){
ipts[i].value = v;
}
}
})
}