js-4 代理Proxy,object原型链, prototype, 继承,
1代理Proxy
1.什么是代理Proxy拦截?
可以对对象,函数,数组进行拦截,将其原本的函数操作改写。
Proxy在目标对象前设一个拦截层,外界对该对象的访问都必须先通过这层拦截,因此提供了一种机制可以对外界的访问进行过滤和改写。
1.obj是原对象,property是实参,函数是要进行的操作
"use strict"const hd = {name:"fff", age :10};const proxy = new Proxy(hd, {get(obj, property){return obj[property];},set(o,p,value){o[p] = value;return true;}});console.log(proxy.name);proxy.name = "lxj";proxy.age = 23;console.log(proxy.name);console.log(proxy);
2.数组 let proxy = new Proxy(lessons, {get (array,key){}})
console.log(proxy[1])
arr是lessons,是原数组, key是下方的“1”,
3.函数代理:function是原函数,
let proxy = new Proxy(func,{
apply(func, obj, args){}
})
proxy.apply({},[5]);
2用代理做数据双向绑定
<body>
<input type="text" v-model="content" />
<input type="text" v-model="title" />
<input type="text" v-model="title" />
<h4 v-bind="title">这里 </h4></body>
<script>function View() {let proxy = new Proxy({},{get(obj,property){},set(obj,property,value){// console.log(obj);obj是空因为没有拦截对象或函数数组//property是刚才传递过来的title,value是发生改变的输入框的内容document.querySelectorAll(`[v-model="${property}"]`).forEach(item =>{item.value = value;//选择所有v-model="title"的文本框,其框的值为value。});document.querySelectorAll(`[v-bind="${property}"]`).forEach(item =>{item.innerHTML = value;//v-bind="title"的元素的显示为value})}})this.init=function () {const els = document.querySelectorAll("[v-model]"); //得到属性名为v-model的元素els.forEach(item => {item.addEventListener("keyup",function () { //遍历这些元素组成的数组,添加监听事件,检测到键盘抬起,做如下动作console.log(this);proxy[this.getAttribute("v-model")] = this.value;//this.getAttribute("v-model")的值是title。this.value是当前输入框接受到的内容//在代理对象proxy中给属性名为title的属性添加值为此输入框的内容,即将我们需要存储的数据存储在此对象中,调用访问器set})})}}new View().init(); //调用init函数
3.表单验证
表单验证,设定条件,取得元素与条件,存入代理,遍历,调用验证方法,通过添加样式来提示是否符合条件。
以后写验证不一定自己手打,用大家常用的库。
1.数组 every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。
every() 方法使用指定函数检测数组中的所有元素:
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
如果所有元素都满足条件,则返回 true。
注意: every() 不会对空数组进行检测。
注意: every() 不会改变原始数组。
2.定义和用法
split() 方法用于把一个字符串分割成字符串数组。
语法
stringObject.split(separator,howmany)
参数 描述
separator 必需。字符串或正则表达式,从该参数指定的地方分割 stringObject。
howmany 可选。该参数可指定返回的数组的最大长度。如果设置了该参数,返回的子串不会多于这个参数指定的数组。如果没有设置该参数,整个字符串都会被分割,不考虑它的长度。
返回值
一个字符串数组。该数组是通过在 separator 指定的边界处将字符串 stringObject 分割成子串创建的。返回的数组中的字串不包括 separator 自身。
但是,如果 separator 是包含子表达式的正则表达式,那么返回的数组中包括与这些子表达式匹配的字串(但不包括与整个正则表达式匹配的文本)。
提示和注释
注释:如果把空字符串 ("") 用作 separator,那么 stringObject 中的每个字符之间都会被分割。
注释:String.split() 执行的操作与 Array.join 执行的操作是相反的。
<body>
<input type="text" validate rule = "max:12,min:3"/>
<input type="text" validate rule = "max:3,isNumber"/>
</body>
<style>.error{border: solid 2px red;}
</style>
<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);//以数字开头的一个或多个数字的字符串}}function ProxyFactory(target) { //代理工厂,return new Proxy(target, {get(target,key){return target[key];},set(target,key, el){//el保存的是的事当前表单元素// console.log(key);const rule = el.getAttribute("rule");// console.log(rule);const validate = new Validate(); //生成一个验证类let state = rule.split(",").every(rule => { //按逗号将两条规则拆分const info = rule.split(":"); //按冒号将验证函数名和参数拆分console.log(info);return validate[info[0]](el.value, info[1]); //实参则是框内的值,和最大值或最小值,在此处调用验证函数// return true;});console.log(state);el.classList[state?"remove":"add"]("error"); //状态为真移除“错误”样式,状态为假添加样式。return true;},});}const proxy = ProxyFactory(document.querySelectorAll("[validate]"))//创建一个代理,代理需验证的元素// console.log(proxy);proxy.forEach((item,index) =>{// console.log(item);item.addEventListener("keyup", function () {proxy[index] = this;//只为触发代理的set函数,没有其他作为。})});
</script>
JSON数据
JSON是结构清晰,方便书写的交流通用格式,方便各种语言之间传递数据。配置文件、包管理等。
标准JSON格式是键值对,键值与属性用双引号包裹,
{
“name”:“dkjfaka”
}
2把对象、数组转成JSON格式
1.把对象转成JSON格式json = JSON.stringify(data,保留某个元素,tab制表位的数量)
2.
php的json转换成对象
let phpJSON = {"url":"kajdkjakf"}
;
let obj = JSON.parse(phpJSON);
obj便是一个对象,php-》json-》js
let data = {name:"jha",data:{title:"php"}};let json = JSON.stringify(data);console.log(json);
3.toJSON,序列化。转换成json时的定制内容
toJSON:function(){
return 。。。
}
4.json -》obj
let obj = JSON.parse(json,(key,value)=》{
做一些操作
return value;
})
原型链
let arr = [];
console.log(arr.proto.proto == Object.prototype);
1.获取对象的原型
Object.isPrototypeOf(hd)
let hd = {};let xj = {};console.log(Object.isPrototypeOf(hd) == Object.isPrototypeOf(xj));
2没有原型的对象:
完全数据字典对象
let xj = Object.create(null, {
name:{
value:“jsdkjf”
}
});
console.log(xj);
let hd = {};console.log(hd);let xj = Object.create(null, {name:{value:"jsdkjf"}});console.log(xj);
{}
: {…}
defineGetter: function defineGetter()
defineSetter: function defineSetter()
lookupGetter: function lookupGetter()
lookupSetter: function lookupSetter()
proto:
constructor: function Object()
hasOwnProperty: function hasOwnProperty()
isPrototypeOf: function isPrototypeOf()
propertyIsEnumerable: function propertyIsEnumerable()
toLocaleString: function toLocaleString()
toSource: function toSource()
toString: function toString()
valueOf: function valueOf()
<get proto()>: function proto()
<set proto()>: function proto()
找到原型.html:13:13
{…}
name: “jsdkjf”
3 proto:每个对象的__proto__属性指向自身构造函数的prototype。
prototype是构造函数在创建对象后所能被对象使用的原型方法
1.每个对象都具有一个名为__proto__的属性;
2.每个构造函数(构造函数标准为大写开头,如Function(),Object()等等JS中自带的构造函数,以及自己创建的)都具有一个名为prototype的方法(注意:既然是方法,那么就是一个对象(JS中函数同样是对象),所以prototype同样带有__proto__属性);
3.每个对象的__proto__属性指向自身构造函数的prototype
let hd = {};
console.log(hd);
// let xj = Object.create(null, {
// name:{
// value:"jsdkjf"
// }
// });
console.log(hd.__proto__);
hd.__proto__.render = function () {console.log("kjsdkfj");
};
hd.render();
4上述系统构造原型的体现
对象的obj.__proto__就是原型的Object.prototype
let obj = {};console.log(obj.__proto__ == Object.prototype);let arr = [];console.log(arr.__proto__ == Array.prototype);
let arr = [];console.log(arr.__proto__ == Array.prototype);Array.prototype.show=function(){console.log("aksjdhaj");}arr.show();
5设置一个对象的原型
设置Object.setPrototypeOf
获取Object.getPrototypeOf
let hd = {name:"dj"}let xj = {name:"xj"}Object.setPrototypeOf(hd,xj);console.log(hd);
6 原型中constructer的引用
在此处User.prototype是重新定义了对象的.prototype,所以要把constructor:User在添加进对象的.prototype中,否则这个对象的对象的.prototype只有一个show函数了。
function User(name) {this.name = name;}User.prototype={show(){console.log(this.name);},constructor:User}let lisi = new User.prototype.constructor("里斯");lisi.show();
7根据对象得到原型中的构造函数,根据构造函数创建对象==》根据对象创建对象。
function User(name) {this.name = name;}User.prototype={show(){console.log(this.name);},constructor:User//一定要有这一个,将原型中的构造函数引用。}let lisi = new User("里斯");console.log(lisi);function createByObject(obj, ...args) {const constructor = Object.getPrototypeOf(obj).constructor;console.log(constructor(...args));return new constructor(...args);}let xj = createByObject(lisi, "ixngjia");xj.show();
8原型链的检测 instanceof
1.//instanceof:检测a的原型链上是否有A.prototype
function A() {}let a = new A();//instanceof:检测a的原型链上是否有A.prototypeconsole.log(a instanceof A);
2.b.isPrototypeOf(a) b在a的原型链上吗,b是a的父级吗?
let b={};let c={};console.log(b.isPrototypeOf(a));
- in检测所有属性
“web” in a web属性是否在a中或a的原型链上呢?
let b={ url:"jksdfja"};let c={name:"jksdhfjks"};Object.prototype.web="jsajfsj";console.log("web" in a);
4.检测当前对象属性:a.hasOwnProperty(“web”)
let b={ url:"jksdfja"};let c={name:"jksdhfjks"};Object.prototype.web="jsajfsj";console.log(a.hasOwnProperty("web"));//false
9想用的函数不在原型链上怎么借用?call apply, bind
DOM借用数组的filter,利用call
let arr = [2,5,7];let res = arr.filter(item => {return item>4;});console.log(res);let btns = document.querySelectorAll("button");let a1 = [].filter.call(btns, item =>{return item.hasAttribute("class");});console.log(a1);
10合理的构造函数声明方法
是把属性放在构造函数中,而方法不放在构造函数中。放在构造函数的原型中。
11 this指向当前对象,不受原型的影响
12 不可再系统Obj中追加方法
所有对象原型链最顶层都是Object,像下面这样做虽然方便但容易造成混乱。
<button onclick="this.hide()">1</button>
</body>
<script>Object.prototype.hide=function () {this.style.display="none";}
</script>
13合适的获取和设置原型的方法
Object.getPrototypeOf(obj)
Object.setPrototypeOf(obj, hd
)
2.不太好的设置原型方法__proto__ 它也是既能设置也能获取原型。
它并不是一个严格意义的属性,是一个访问器getter和setter,会对设置的值进行判断如果不是对象就不能设置原型。若非要设置非对象obj.proto = “dfas”.可以先使得原型为空,添加此属性
obj.proto = hd
console.log(obj.proto)
3.create只能设置原型不能获取原型。
let hd = Object.create(user);
14继承:
1.继承是原型的继承,不是改变构造函数的原型
hd.prototype.proto = user.prototype
2.Admin.prototype = Obiect.create(User.prototype);
Object,defineProperty(Admin.prototype,“constructor”,{
value: Admin,
enumerable:false
});
15使用父类构造函数进行初始化
User.call(this,name,age);要把当前对象传递过去否则不成功
function User(name, age) {this.name=name;this.age=age;}User.prototype.show=function(){console.log(this.name,this.age);}function Admin(name, age) {User.call(this,name,age);}Admin.prototype=Object.create(User.prototype);let xj = new Admin("hdjh", 12);xj.show();
16对象工厂
function User(name, age) {this.name=name;this.age=age;}function admin(name, age) { //对象工厂const instance = Object.create(User.prototype); //新的对象console.log(instance);User.call(instance,name,age);instance.role = function () {console.log("role");};instance.show=function(){console.log(this.name,this.age);}return instance;}let xj = new admin("刘兴加", 23);xj.show();xj.role();
17合并类实现类似多继承mixin方法
将不同的对象合并取得它们的方法
member.prototype = Object.assign(member.prototype,Request,Credit);
这样member就继承了二者的方法和属性。实现了多继承。
此时member调用request方法的super指向的是request的原型,因为上述的赋值是引用其他类的函数,并不是这个函数就在member的原型中了。
18Tab选项卡效果基类、业务管理类、开放api
tab构造函数传参方式采用了args,接收到对象后,在与默认参数合并。
所有的动作再开始时重置,默认a1.
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<style>* {padding: 0;margin: 0;}body {padding: 20px;display: flex;justify-content: center;align-items: flex-start;width: 100vw;height: 100vh;}main {width: 400px;flex-direction: column;position: relative;margin-right: 20px;}main nav {display: flex;height: 50px;align-items: center;}main nav a,main nav span {background: #95a5a6;margin-right: 0px;padding: 10px 20px;border: solid 1px #333;color: #fff;text-decoration: none;}main nav a:first-of-type,main nav span:first-of-type{background: #e67e22;}section {height: 200px;width: 100%;background: #f1c40f;position: absolute;font-size: 5em;/* display: none; */}.hd-tab section:first-of-type {display: block;}section:nth-child(even) {background: #27ae60;}
</style>
<body>
<main class="tab1"><nav><a href="javascript:;">后盾人</a><a href="javascript:;">hdcms</a></nav><section>1</section><section>2</section>
</main>
<main class="tab2"><nav><span href="javascript:;">后盾人</span><span href="javascript:;">hdcms</span></nav><section>1</section><section>2</section>
</main>
</body>
<script>function extend(sub,sup) { //继承原型的工厂sub.prototype = Object.create(sup.prototype);sub.prototype.constructor = sub;}function Animation() { //变化}Animation.prototype.show=function () { //显示this.style.display="block";};Animation.prototype.hide=function () { //隐藏this.style.display="none";};Animation.prototype.background=function (color ) { //改变背景颜色this.style.backgroundColor=color;};function Tab(args) {args = Object.assign({el:null, link:"a", section:"section", callback:null},args);this.tab = document.querySelector(args["el"]);this.links = this.tab.querySelectorAll(args["link"]);this.sections = this.tab.querySelectorAll(args["section"]);// console.log(this.sections);this.callback = args["callback"];}extend(Tab,Animation);Tab.prototype.run=function () {this.bindEvent();this.reset();this.action(0);}Tab.prototype.bindEvent=function () {this.links.forEach((el, i) =>{el.addEventListener("click", () =>{this.reset();this.action(i); //i是下标if(this.callback) this.callback();})});}Tab.prototype.action=function (i) {this.background.call(this.links[i], "#e67e22");this.show.call(this.sections[i]);}Tab.prototype.reset=function () {this.links.forEach((el,i)=>{this.background.call(this.links[i], "#95a5a6");this.hide.call(this.sections[i]);})}new Tab({el: ".tab1",callback() {console.log("houdurnen.com");}}).run();new Tab({el: ".tab2", link: "span", callback: function () {console.log("刘兴加");}}).run();
</script>
</html>
js-4 代理Proxy,object原型链, prototype, 继承,相关推荐
- 详解JS原型链与继承
详解JS原型链与继承 JavaScript 目录 摘自JavaScript高级程序设计: 概念 确定原型和实例的关系 原型链的问题 借用构造函数 组合继承 原型继承 寄生式继承 寄生组合式继承 new ...
- 深入理解原型链与继承(详解JS继承原理)
文章目录 原型链与继承 new 关键字的执行过程 构造函数.实例对象和原型对象 原型链的概念及图解 第一层`__proto__`指向:实例对象 第二层`__proto__`指向:`Function.p ...
- JS基于原型链的继承和基于类的继承学习总结
1. new关键字创建一个对象的过程 (1) 创建一个空的简单对象(即{}) (2)为步骤1新创建的对象添加属性_proto_,该属性连接至构造函数的原型对象 (3)将步骤1新创建的对象作为this的 ...
- JavaScript原型链实现继承
js 继承 原型链 默认的原型 确定原型和实例的关系 谨慎定义方法 原型链的问题 借用构造函数 组合继承 最常用的继承模式 原型式继承 寄生式继承 寄生组合式继承 是引用类型最理想的继承范式 学习记录 ...
- JavaScript 原型链和继承面试题
JavaScript 原型链和继承问题 JavaScript 中没有类的概念的,主要通过原型链来实现继承.通常情况下,继承意味着复制操作,然而 JavaScript默认并不会复制对象的属性,相反,Ja ...
- JavaScript (四) ——构造函数原型 , 原型链 和继承
原型 所有引用类型都有一个_proto_属性, 属性值是对象 所有函数都有一个prototype属性 , 属性值是一个对象 所有引用类型的_proto_属性 , 都指向其构造函数的prototype ...
- 对Javascript 类、原型链、继承的理解
一.序言 和其他面向对象的语言(如Java)不同,Javascript语言对类的实现和继承的实现没有标准的定义,而是将这些交给了程序员,让程序员更加灵活地(当然刚开始也更加头疼)去定义类,实现继承 ...
- 图解原型链及其继承优缺点
原型链 上篇文章中我们介绍了原型链的概念,即每个对象拥有一个原型对象,通过__proto__ 指针指向上一个原型 ,并从中继承方法和属性,同时原型对象也可能拥有原型,这样一层一层,最终指向 null, ...
- JS中关于构造函数、原型链、prototype、constructor、instanceof、__proto__属性
在Javascript不存在类(Class)的概念,javascript中不是基于类的,而是通过构造函数(constructor)和原型链(prototype chains)实现的.但是在ES6中引入 ...
最新文章
- java 进程睡眠_Linux进程的睡眠和唤醒简析
- dgl库之高级用法dgl.DGLGraph.update_all
- 【移动开发】Android中强大的适配功能----Fragment(碎片)总结
- LiveQing全新升级的RTMP流媒体服务器支持HLS(m3u8)、RTMP、HTTP-FLV高性能分发
- 编写脚本自动部署反向代理、web、nfs
- fast.ai 深度学习笔记:第一部分第一课
- Docker中快速安装Mysql
- 2.15.9.menuconfig的实验学习思路
- MonkeyRunner_API
- Vue 移动端跳到手机拨打电话界面的几种方法
- 银河帝国----基地前奏
- 《笑傲江湖》清心普善咒——曲谱(琴箫合奏曲)
- 计数器(Verilog)
- MySQL中的uuid()和uuid_short()函数
- 哪里能找到搞笑自媒体素材?学会技巧才能提高创作效率
- python2使用openpyxl版本_python openpyxl 2.5.4 版本 excel常用操作封装
- knn分类算法实现手写体数字识别python
- 软工大作业·倾物语(三)
- Zabbix6.0使用教程 (一)—zabbix新增功能介绍2
- 刘德华徐静蕾新片《投名状》