js-4 代理Proxy,object原型链, prototype, 继承,

47 篇文章 0 订阅

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.prototype
    console.log(a instanceof A);

2.b.isPrototypeOf(a) b在a的原型链上吗,b是a的父级吗?

let b={};
    let c={};
    
    console.log(b.isPrototypeOf(a));
  1. 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>
### 回答1: fiori-tools-proxy是一个帮助开发人员在本地开发SAP Fiori应用的工具。它可以通过代理方式连接到HANA数据库,使开发人员能够在本地测试应用程序而无需实际连接到HANA数据库。这样可以大大简化开发过程,并减少对生产环境的影响。 fiori-tools-proxy需要在本地安装并配置,然后在应用程序中使用代理地址连接到HANA数据库。具体的安装和配置方法可以参考SAP的文档和教程。 ### 回答2: Fiori Tools Proxy 可以用于连接 SAP HANA 数据库。SAP HANA 是一款高性能、内存数据库,用于存储和处理企业级数据。通过 Fiori Tools Proxy 可以实现与 HANA 数据库的连接,方便开发人员在 SAP Fiori 开发项目中使用 HANA 数据。 连接 HANA 数据库需要进行一些配置工作,包括设置代理和配置连接参数。首先,我们需要在 Fiori Tools Proxy 中设置 HANA 数据库的代理代理充当一个中间层,它会接收来自 SAP Fiori 应用的请求,然后将其转发给 HANA 数据库。设置代理的目的是为了保护 HANA 数据库的安全性,并提供更好的性能和灵活性。 在 Fiori Tools Proxy 中,我们还需要配置连接到 HANA 数据库的参数。这些参数包括 HANA 数据库的主机名、端口号、用户名和密码等。通过提供正确的参数,Fiori Tools Proxy 就可以建立与 HANA 数据库的连接。连接成功后,开发人员可以通过 Fiori 工具集来访问和操作 HANA 数据库中的数据。 通过 Fiori Tools Proxy 连接 HANA 数据库可以实现多种功能。开发人员可以通过 SAP Fiori 应用来查询、更新和删除数据库中的数据。同时,还可以执行更高级的操作,如创建和管理数据库表、执行 SQL 查询等。这样,开发人员就可以更高效地开发和维护企业级应用程序,并充分利用 HANA 数据库的强大功能。 总之,Fiori Tools Proxy 提供了一种方便的方式来连接 SAP HANA 数据库。通过配置代理和连接参数,开发人员可以在 SAP Fiori 开发项目中轻松地访问和操作 HANA 数据库中的数据。这样,他们可以更好地开发和管理企业级应用程序,提高工作效率和质量。 ### 回答3: Fiori Tools Proxy是一个用于连接HANA数据库的工具。HANA是一个内存计算数据库平台,具有高速和高性能的数据处理能力。在使用Fiori应用程序时,我们需要与HANA进行通信,以从数据库中检索和处理数据。 使用Fiori Tools Proxy连接HANA,可以实现与HANA数据库的无缝集成。它提供了一个代理服务器,作为Fiori应用程序和HANA之间的中间层。代理服务器处理Fiori应用程序发送的请求,并将其转发到HANA数据库。 Fiori Tools Proxy的连接过程相对简单。首先,我们需要在Fiori Tools Proxy上配置HANA数据库的连接信息,例如数据库服务器的主机名、端口号和认证凭证等。然后,将Fiori应用程序中的数据请求发送到Fiori Tools Proxy的URL地址。Fiori Tools Proxy会拦截这些请求,并将其转发到配置好的HANA数据库。HANA处理请求后,将数据结果返回给Fiori Tools Proxy,再由Fiori Tools Proxy返回给Fiori应用程序。 使用Fiori Tools Proxy连接HANA具有许多好处。首先,它提供了一个安全的通信通道,确保数据在传输过程中的机密性和完整性。其次,它可以有效地管理并优化对HANA数据库的请求,提高应用程序的性能和响应速度。此外,Fiori Tools Proxy还提供了一些调试和监控功能,帮助我们追踪和定位与HANA的通信问题。 总之,Fiori Tools Proxy是连接Fiori应用程序和HANA数据库的重要工具,通过它,我们可以轻松地实现两者之间的通信和集成。它提供了安全、高效和可靠的连接,确保了应用程序的性能和数据的安全性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值