- es6 以前 - api - https://www.w3cschool.cn/javascript/dict
- es6 - 中文文档
文章目录
- # 为什么?
- # 解构
- # 原型
- ## hasOwnProperty 检测
- ## 'concat' in arr 检测
- ## setPrototypeOf(新, 原型)
- ## 计算属性 stringify 、 assign 使用
- ## Object.keys / Object.values / Object.entries
- ## for ... in / for .... of
- ## 遍历操作和DOM绘制(后面框架会更简单)
- ## 浅拷贝
- ## 深拷贝
- ## 工厂函数 创建对象
- ## 构造函数创建对象
- ## js 的 数据类型 、 封装类型 new Object()、Number()、 String()、Boolean()、 new Date()、RegExp() 、 new Function();
- ## 对象的 封装、 抽象(这个抽象和java不同)
- ## 对象属性 保护(不能修改/删除/重新配置) 、 Object.getOwnPropertyDescriptor
- ## defineProperty
- ## 封闭对象 Object.seal() / Object.isSealed()
- ## 冻结 freeze
- 访问器
- # 构造函数 、 class语法糖 中使用访问器
- # Token 的读写
- JSON
# 为什么?
首先,看 函数编程
的 求和
let name = '向军' ;
let grade = [
{name: 'js' , score: 99} ,
{name: 'docker' , score: 76}
] ;
function average(grade , name) {
let total = grade.reduce((t,l) => t+l.score , 0 ) ;
return `${name}的平均成绩是:${total/grade.lengh}` ;
//array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
}
console.log(average(grade , name ));
对象编程
let user = {
name: '向军' ,
grade = [
{name: 'js' , score: 99} ,
{name: 'docker' , score: 76}
] ,
average: function() {
let total = this.grade.reduce((t,l) => t+l.score , 0 ) ;
return `${this.name}的平均成绩是:${total/grade.lengh}` ;
//array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
}
}
console.log(average());
或者简写
let user = {
name: '向军' ,
grade = [
{name: 'js' , score: 99} ,
{name: 'docker' , score: 76}
] ,
average () {
let total = this.grade.reduce((t,l) => t+l.score , 0 ) ;
return `${this.name}的平均成绩是:${total/grade.lengh}` ;
//array.reduce(function(total, currentValue, currentIndex, arr), initialValue)
}
}
console.log(average());
减少 函数编程 意大利面条式
的程序
遍历
let user = {
name: '向军',
'my age': 18
}
for(const key in user) {
console.log(user[key]) ;
}
## 添加 / 删除 属性(方法)
user.age= 19 ;
user.get=function() {
return `${this.name}的年龄${this.age}`;
}
console.log(user.get());
delete user.age ;
console.log(user.get());
## 对象的引用
https://www.bilibili.com/video/av77733273?p=3
## 展示语法 、 参数合并
//展开语法
let arr = [1,2,3] ;
let a = [... arr , 5, 6 , 7] ;
console.log(a);
let user = {name: 'a' , age : 22} ;
let hd = {...user , lang: 'zh'};
console.log(hd);
function upload(params) { // 参数合并
let config = {
type: '*.jpeg,*.png' ,
size: 10000 ;
} ;
config = {...config, ...params};
console.log(config);
}
console.log(upload({size:99 , type: '*.gif'}));
文章目录
- # 为什么?
- # 解构
- # 原型
- ## hasOwnProperty 检测
- ## 'concat' in arr 检测
- ## setPrototypeOf(新, 原型)
- ## 计算属性 stringify 、 assign 使用
- ## Object.keys / Object.values / Object.entries
- ## for ... in / for .... of
- ## 遍历操作和DOM绘制(后面框架会更简单)
- ## 浅拷贝
- ## 深拷贝
- ## 工厂函数 创建对象
- ## 构造函数创建对象
- ## js 的 数据类型 、 封装类型 new Object()、Number()、 String()、Boolean()、 new Date()、RegExp() 、 new Function();
- ## 对象的 封装、 抽象(这个抽象和java不同)
- ## 对象属性 保护(不能修改/删除/重新配置) 、 Object.getOwnPropertyDescriptor
- ## defineProperty
- ## 封闭对象 Object.seal() / Object.isSealed()
- ## 冻结 freeze
- 访问器
- # 构造函数 、 class语法糖 中使用访问器
- # Token 的读写
- JSON
# 解构
## 解构赋值
let user = {name: 'aaa' , age : 18} ;
let {name: n , age: a } = user ;
console.log(n);
console.log(age);
let user = {name: 'aaa' , age : 18} ;
let {name: name , age: age } = user ;
console.log(n);
console.log(age);
let user = {name: 'aaa' , age : 18} ;
let {name , age } = user ;
console.log(n);
console.log(age);
function hd() {
return {name: 'aaa' , age : 18} ;
}
let {name , age } = user ;
console.log(n);
console.log(age);
function user({name, age}) {
console.log(name, age);
}
user({name: 'a' , age : 22}); // 常用接收语后台传值
let {random} = Math;
console.log(random()); // 直接random 函数 运行
## 严格模式 解构
https://www.bilibili.com/video/av77733273?p=6
非严格模式
//'use strict'
({name , age } = {name: 'a' , age : 22} ) // 非严格模式 这样可以
严格模式
'use strict'
let {name , age } = {name: 'a' , age : 22} // 声明语句声明了就行
作用? 健壮
## 解构操作 - 简写 、 变量解构
let web = {name: 'a' , age : 22} ;
let {name } = web ;
let name = 'aa' , url = 'aaabbbb' ;
let opt = {name , url } ;
## 解构操作 、 多层对象
let hd = {
name : 'aa' ,
lesson : {
title : 'js'
}
} ;
let {
name ,
lesson : {title }
} = hd ;
console.log(title);
## 解构 默认值 、 配置项合并
let user = {name:'aa' , url : 'abasbasd'}
let {name , url , title ='hdsfda' } = user ;
console.log(name , url , title);
可以做参数的合并
function createElement(options) {
let {
width= 200 ,
height = 100 ,
backgroundColor = 'red'
} = options ;
const div = document.createElement('div');
div.style.width = width + 'px' ;
div.style.height = height + 'px' ;
div.style.backgroundColor = backgroundColor + 'px' ;
document.body.appendChild(div);
}
createElement({width:300});
文章目录
- # 为什么?
- # 解构
- # 原型
- ## hasOwnProperty 检测
- ## 'concat' in arr 检测
- ## setPrototypeOf(新, 原型)
- ## 计算属性 stringify 、 assign 使用
- ## Object.keys / Object.values / Object.entries
- ## for ... in / for .... of
- ## 遍历操作和DOM绘制(后面框架会更简单)
- ## 浅拷贝
- ## 深拷贝
- ## 工厂函数 创建对象
- ## 构造函数创建对象
- ## js 的 数据类型 、 封装类型 new Object()、Number()、 String()、Boolean()、 new Date()、RegExp() 、 new Function();
- ## 对象的 封装、 抽象(这个抽象和java不同)
- ## 对象属性 保护(不能修改/删除/重新配置) 、 Object.getOwnPropertyDescriptor
- ## defineProperty
- ## 封闭对象 Object.seal() / Object.isSealed()
- ## 冻结 freeze
- 访问器
- # 构造函数 、 class语法糖 中使用访问器
- # Token 的读写
- JSON
# 原型
## hasOwnProperty 检测
只看自己 , 不看原型
## ‘concat’ in arr 检测
看自己 也看原型 原型链
https://www.bilibili.com/video/av77733273?p=12
## setPrototypeOf(新, 原型)
let a = {name : 'aa'} ;
let b = {url: 'aba'} ;
Object.setPrototypeOf(a , b );
console.log(a);
function oss(options) {
if(!options.hasOwnProperty('host')) {
throw new Error('必须设置主机地址');
}
}
oss({user : 'admin'}) ;
## 计算属性 stringify 、 assign 使用
let lessons = [
{
title: "媒体查询响应式布局",
click: 89,
price: 12
} ,
{
title: "FLEX 弹性盒模型",
click: 45,
price: 120
} ,
{
title: "GRID 栅格系统",
click: 19,
price: 67
} ,
{
title: "盒子模型详解",
click: 29,
price: 300
} ,
];
let res = lessons.reduce((obj , cur , index) => {
obj[`${cur.title}-${index+1}`] = cur ;
return obj ;
} , {});
let s = JSON.stringify(res , null , 2);
console.log(s);
使用assign
let hd = Object.assign({a:1} ,{b:2});
console.log(hd); //{a:1 , b:2}
function upload(params){
let options = {
size: 1999
} ;
options = Object.assign(options , params);
console.log(JSON.stringify(options , null , 2 ));
}
upload({size: 99, type: 'jpeg'});
与assign
类似的库
jQuery.extend()
lodash
## Object.keys / Object.values / Object.entries
let lessons = [
{
title: "媒体查询响应式布局",
click: 89,
price: 12
} ,
{
title: "FLEX 弹性盒模型",
click: 45,
price: 120
} ,
{
title: "GRID 栅格系统",
click: 19,
price: 67
} ,
{
title: "盒子模型详解",
click: 29,
price: 300
} ,
];
console.log(Object.keys(lessons));
console.log(Object.values(lessons));
let a = Object.entries(lessons) //转换为数组形式
console.log(JSON.stringify(a, null, 3));
## for … in / for … of
in 遍历
of 迭代(不能 迭代 对象)
let lessons = [
{
title: "媒体查询响应式布局",
click: 89,
price: 12
} ,
{
title: "FLEX 弹性盒模型",
click: 45,
price: 120
} ,
{
title: "GRID 栅格系统",
click: 19,
price: 67
} ,
{
title: "盒子模型详解",
click: 29,
price: 300
} ,
];
let hd = lessons[0] ;
for(const key in hd) {
console.log(hd[key]);
}
for(const interator of hd){ // 这样不行的
}
for(const interator of Object.keys(hd)){
console.log(hd[iterator]);
}
for(const interator of Object.values(hd)){
console.log(iterator);
}
for(const interator of lessons){ // 数组 正常迭代
console.log(iterator);
}
//解构也是可以的
for( const [key , value] of Object.entries(hd)) {
console.log(value) ;
}
## 遍历操作和DOM绘制(后面框架会更简单)
let lessons = [
{name:'js' , click: 999} ,
{name:'node' , click: 127}
] ;
let ul = document.createElement('ul');
for (const lesson of lessons) {
let li = document.createElement('li') ;
li.innerHTML = `课程:${lesson.name}${lesson.click}`;
ul.appendChild(li);
}
document.body.appendChild(ul);
## 浅拷贝
简单理解:(不完全拷贝)
有循环(单层情况 )
let hd = {name: '后的男人' , url : 'abc.com'} ;
let obj = {} ;
for (const key in hd) {
obj[key] = hd[key] ;
}
console.log(obj);
有api
let hd = {name: '后的男人' , url : 'abc.com'} ;
let obj = Object.assign({} , hd);
有合并
let hd = {name: '后的男人' , url : 'abc.com'} ;
let obj = {...hd} ;
obj.name = 'xxx'
console.log(hd)
## 深拷贝
简单理解:(完全拷贝)
上面遍历的问题
let data = {
name: 'bsadasfsdafdsafdsafdsafaf' ,
user : {
name: 'sgfag'
}
};
function copy(object) {
let res = {} ;
for(const key in object ) {
res[key] = object[key] ;
}
return res;
}
let hd = copy(data) ;
hd.user.name = 'aaaaaaaaaa'
console.log(JSON.stringify(hd , null , 2));
console.log(JSON.stringify(data , null , 2));
递归解决
let data = {
name: 'bsadasfsdafdsafdsafdsafaf' ,
user : {
name: 'sgfag'
}
};
function copy(object) {
let res = {} ;
for(const key in object ) {
res[key] = typeof object[key] == 'object' ? copy(object[key]) : object[key] ;
}
return res;
}
let hd = copy(data) ;
hd.user.name = 'aaaaaaaaaa'
console.log(JSON.stringify(hd , null , 2));
console.log(JSON.stringify(data , null , 2));
那数组呢?
let data = {
name: 'bsadasfsdafdsafdsafdsafaf' ,
user : {
name: 'sgfag'
} ,
ar : [1 ,2 ]
};
function copy(obj) {
let res = obj instanceof Array ? [] : {} ;
for(const [k , v ] of Object.entries(obj)) {
res[k] = typeof v == 'object' ? copy(v) : v ;
}
return res;
}
let hd = copy(data) ;
console.log(JSON.stringify(hd , null , 2));
console.log(JSON.stringify(data , null , 2));
## 工厂函数 创建对象
function user(name , age) {
return {
name ,
age ,
show() {
console.log(`name=${name} age=${age}`);
}
}
}
## 构造函数创建对象
'use strict' ;
function User(name) {
this.name = name ;
this.show = function() {
console.log(this.name);
}
return this; // 可以不返回,系统默认返回
}
let xj = new User('向军') ;
xj.show() ;
let func = xj.show;
func() ;
这里,不用严格模式,func 的 this 是 window !
因此,一定要严格模式
## js 的 数据类型 、 封装类型 new Object()、Number()、 String()、Boolean()、 new Date()、RegExp() 、 new Function();
js 的构造函数 、 数据类型
let o = new Object() ;
o.name = 'hdc、' ;
console.log(o);
let n = new Number(1) ;
console.log(n.valueOf());
console.log(n+3);
let s = new String('houdunren');
console.log(s.valueOf());
console.log(s.toUpperCase());
let b = new Boolean(true);
console.log(typeof b.toString); //string
console.log(typeof b.valueOf() ); //boolean
let d = new Date() ;
console.log(d.valueOf());
let r = new RegExp('\\d+'); //数字
console.log(r.valueOf()); // /\d+/
console.log(r.test('abc')); //false
function hd() {}
console.log(hd.constructor); // Function()
let User = new Function('name' , ` this.name = name ; this.show = function() { console.log(this.name); } `);
let xj = new User('xx') ;
xj.show();
## 对象的 封装、 抽象(这个抽象和java不同)
视频:https://www.bilibili.com/video/av77733273?p=20
js抽象的解释:https://blog.csdn.net/Manson_Wang/article/details/96462628
function User(name , age ) {
this.name = name ;
this.age = age ;
this.show = function () {
console.log(`${this.name}${this.info()}`) ;
}
this.info = function() {
return this.age>50 ? '老年' : '青年' ;
}
}
let xj = new User('nam' , 10) ;
xj.info = function() {return '???'}
xj.show() ; // 青年???
function User(name , age ) {
let data = {name, age} ;
this.show = function() {
console.log(`${data.name}${info()}`) ;
}
let info = function() {
return this.age>50 ? '老年' : '青年' ;
}
}
let xj = new User('nam' , 10) ;
xj.info = function() {return '???'}
xj.show() ;
## 对象属性 保护(不能修改/删除/重新配置) 、 Object.getOwnPropertyDescriptor
const user = {
name : 'aaaaaaaa' ,
age: 18
}
console.log(
JSON.stringify(Object.getOwnPropertyDescriptor(user , 'name') , null , 2)
)
console.log(
JSON.stringify(Object.getOwnPropertyDescriptors(user ) , null , 2)
)
writable: 可修改,
enumerable: 可遍历 / 直接查看,
configurable: 添加 / 删除 属性
## defineProperty
const user = {
age : 18
}
console.log(
JSON.stringify(Object.getOwnPropertyDescriptor(user, 'age'))
)
Object.defineProperty(user , 'name' , {
value : 'hdr'
}) ;
console.log(user)
console.log(user.name)
console.log(Object.getOwnPropertyDescriptor(user , 'name'))
'use strict' ;
const user = {
age : 18
}
console.log(
JSON.stringify(Object.getOwnPropertyDescriptor(user, 'age'))
)
Object.defineProperty(user , 'name' , {
value : 'hdr' ,
writable: true, // 修改
enumerable: true , // 遍历
configurable : true // 添加/ 删除 属性 (指定之后不可修改)
}) ;
console.log(user)
user.name = "向军" ;
console.log(user)
delete user.name ;
console.log(user)
configurable: false 注意点
<mark>configurable: false 之后,不能重新configurable:true 之类的操作</mark>
因为,已经 ‘定义’ 了 ‘不能再定义’
当然,修改其他两个 是可以的
'use strict' ;
const user = {
name: '向军' ,
age : 18
}
Object.defineProperties(user , {
name: {
value : 'hdr' ,
writable: true,
enumerable: false ,
configurable : true
} ,
age: {
value: '后的男人',
writable: true ,
enumerable: false ,
configurable: true
}
}) ;
console.log(user) ;
console.log(user.name) ;
console.log(user.age) ;
'use strict' ;
const user = {
name: '向军' ,
age : 18
}
console.log(
JSON.stringify(Object.getOwnPropertyDescriptor(user , 'age'))
) ;
Object.defineProperty(user , 'name' , {
value: '后盾人' ,
writable: false
});
console.log(user.name) ;
user.name = "向军" ;
console.log(user.name) ;
严格模式下 报错
## 封闭对象 Object.seal() / Object.isSealed()
'use strict' ;
const user = {
name: '向军' ,
age : 18
}
console.log(
JSON.stringify(Object.getOwnPropertyDescriptors(user ), null , 2)
)
Object.seal(user)
console.log(
JSON.stringify(Object.getOwnPropertyDescriptors(user ), null , 2)
)
Object.seal(user)
<mark>但是 封闭 不等于 configurable : false</mark>
'use strict' ;
const user = {
name: '向军' ,
age : 18
}
Object.defineProperty(user, 'age' , {
configurable : false
})
console.log(
JSON.stringify(Object.getOwnPropertyDescriptors(user ), null , 2)
)
console.log(Object.isSealed(user))
## 冻结 freeze
'use strict' ;
const user = {
name: '向军' ,
age : 18
}
Object.freeze(user) ;
console.log(
JSON.stringify(Object.getOwnPropertyDescriptors(user) , null , 2)
)
if(!Object.isFrozen(user)) {
user.site = 'hahaha' ;
user.name= '李磊' ;
delete user.name ;
}
console.log(user)
访问器
'use strict' ;
const user = {
data: { name: '后盾人', age: 10 } ,
set age(value) {
console.log('set...') ;
if(typeof value != 'number' || value<10 || value>100){
throw new Error("年龄格式错误");
}
this.data.age = value ;
},
get age() {
console.log('get...') ;
return this.data.age;
}
};
//user.age=1999 ;
user.data.age = 11 ;
console.log(user.data.age) ;
user.age = 13 ;
console.log(user.age)
## 访问器 伪造属性
'use strict' ;
let Lesson = {
list: [
{name: 'js', price: 100} ,
{name: 'mysql', price: 211} ,
{name: 'vue.js', price: 98}
],
get total() {
return this.list.reduce((t,l) =>{
return t += l.price ;
}, 0) ;
}
};
console.log(Lesson.total) ;
Lesson.total = 8388 ;
console.log(Lesson.total) ;
访问器 优先级高
'use strict' ;
const user = {
name: '后盾热',
age: 10 ,
set name(value){
console.log(value+'-后盾热');
}
};
user.name='hdcms' ;
console.log(user) ;
Symbol
- symbol 讲解 - https://blog.csdn.net/LawssssCat/article/details/104234660
访问器 批量设置属性
'use strict' ;
const web = {
name: '后盾人',
url: 'houdunren.com' ,
set site(value) {
//console.log(value) ;
[this.name, this.url] = value.split(',') ;
},
get site() {
return `${this.name}的网址是${this.url}` ;
}
};
web.site = '开源产品,www.hdcms.com';
console.log(web.site)
## 访问器 优先级
//'use strict' ;
const DATA = Symbol() ;
const user = {
[DATA]: {
name : ''
} ,
set name(value) {
this[DATA].name=value;
},
get name() {
return this[DATA].name;
}
};
user.name= "agasd" ;
console.log(user.name) ;
# 构造函数 、 class语法糖 中使用访问器
'use strict' ;
class User {
constructor(name , age){
this.data={ name , age };
}
get name() {
return this.data.name;//闭包特性
}
set name(value) {
if(value.trim()=='' || value.length>20) {
throw new Error('用户名不合法')
}
this.data.name = value ;
}
get age() {
return this.data.age;//闭包特性
}
set age(value) {
this.data.age = value ;
}
}
let cms = new User('向军', 19) ;
//cms.name = '' ;
console.log(cms) ;
console.log(
JSON.stringify(cms , null , 2)
) ;
加上 Symbol
'use strict' ;
const DATA = Symbol() ;
class User {
constructor(name , age){
this[DATA]={ name , age };
}
get name() {
return this[DATA].name;//闭包特性
}
set name(value) {
if(value.trim()=='' || value.length>20) {
throw new Error('用户名不合法')
}
this[DATA].name = value ;
}
get age() {
return this[DATA].age;//闭包特性
}
set age(value) {
this[DATA].age = value ;
}
}
let cms = new User('向军', 19) ;
//cms.name = '' ;
console.log(cms) ;
console.log(
JSON.stringify(cms , null , 2)
) ;
# Token 的读写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script> 'use strict' //token let Request = { set token(content) { localStorage.setItem('token',content) ; }, get token() { let token = localStorage.getItem('token') ; if(!token) { alert('请登录') } return token ; } } Request.token = 'sadgsad5453s4daf3sd1gdsagdsa' ; console.log(Request.token) ; </script>
</body>
</html>
Proxy ***拦截
中文 api - http://caibaojian.com/es6/proxy.html
'use strict' ;
// 对象的***: 对整个对象进行***
const hd = { name:'后盾人' };
const proxy = new Proxy(hd,{
get(obj, property) {
return obj[property] ;
},
set(obj, property , value) {
obj[property] = value ;
return true ; // 严格模式下 必须返回
}
});
console.log(proxy.name) ;
proxy.name = '向军'
console.log(proxy.name);
console.log(proxy)
console.log(hd)
***函数
function factorial(num) { //阶乘
return num==1?1:num *factorial(num-1) ;
}
let proxy = new Proxy(factorial, {
apply(func , obj , args) {
console.log(func) ;
}
});
proxy(5) ;
计时 : console.timeEnd(‘run’) ;
## 阶乘 执行时间
function factorial(num) { //阶乘
return num==1?1:num *factorial(num-1) ;
}
let proxy = new Proxy(factorial, {
apply(func , obj , args) {
console.time('run') ;
func.apply(this, args) ;
console.timeEnd('run') ;
//console.log(func) ; // function
}
});
proxy.apply(this,[100]) ;
数组*** 拦截操作
const lessons = [
{
title: '媒体查询式布局',
category: 'css'
},
{
title: 'FLEX 弹性盒模型',
category: 'css'
},
{
title: 'MYSQL多表查询随意操作',
category: 'css'
}
];
let proxy = new Proxy(lessons, {
get(array,key) {
const title = array[key].title ;
console.log(title) ;
const len = 7 ;
array[key].title =
title.length>len
? title.substr(0, len) + '.'.repeat(3)
: title ;
return array[key] ;
}
}) ;
console.log(
JSON.stringify(proxy[2],null,2)
)
VUEJS 数据绑定的容器更新
https://www.bilibili.com/video/av77733273?p=35
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="text" v-model='title'>
<input type="text" v-model='title'>
<h4 v-bind='title'>这里也会更新</h4>
<script>
function View() {
let proxy = new Proxy({} , {
get(obj, property) {} ,
set(obj,property,value) {
console.log(value) ;
}
})
this.init = function() {
const els = document.querySelectorAll('[v-model]') ;
els.forEach(item => {
item.addEventListener('keyup' ,function() { // this 键入的 input
proxy[this.getAttribute('v-model')] = this.value ;
});
});
};
}
new View().init() ;
</script>
</body>
</html>
双向页面绑定的 渲染
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="text" v-model='content'>
<input type="text" v-model='title'>
<input type="text" v-model='title'>
<h4 v-bind='title'>这里也会更新</h4>
<script>
function View() {
let proxy = new Proxy({} , {
get(obj, property) {} ,
set(obj,property,value) { // 如果是严格模式,要返回true
document.querySelectorAll(`[v-model="${property}"]`)
.forEach(item=> {
item.value=value;
});
document.querySelectorAll(`[v-bind="${property}"]`)
.forEach(item => {
item.innerHTML = value ;
})
// return true 能避免 'set' on proxy: trap returned falsish for property 'xxx' 异常
}
})
this.init = function() {
const els = document.querySelectorAll('[v-model]') ;
els.forEach(item => {
item.addEventListener('keyup' ,function() { // this 键入的 input
proxy[this.getAttribute('v-model')] = this.value ;
});
});
};
}
new View().init() ;
</script>
</body>
</html>
表单校验
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.error{
border-color: red;
}
</style>
</head>
<body>
<input type="text" validate rule='max:12,min:3'>
<input type="text" validate rule='max:3,isNumber'>
<script>
'use strict' ;
class Validate{
max(value , len){
return value.length <= len ;
}
min(value,len) {
return value.length >= len ;
}
isNumber(value) {
return /^\d+$/.test(value);
}
}
const validate = new Validate() ;
function ProxyFactory(target) {
return new Proxy(target , {
get(target, key) {
return target[key] ;
},
set(target, key, el) { // el 传入的 this
const rules = el.getAttribute('rule');
let state = rules.split(',').every(rule => { //都是真 才真
const info = rule.split(':') ;
return validate[info[0]](el.value,info[1] ) ;
})
el.classList[state?'remove':'add']('error') ;
return true ; // 因为是严格模式,所以要返回 true
}
});
}
const proxy = ProxyFactory(document.querySelectorAll('[validate]'))
proxy.forEach((item,i) => {
item.addEventListener("keyup",function() {
proxy[i] = this ; //只是为了触发***事件
})
})
</script>
</body>
</html>