《你不知道的JavaScript上卷》读书笔记

第一次尝试用思维导图记笔记,感觉还不错~~~不过还是改不了我读书笔记写成抄书笔记的毛病 =。=

因为开始学JS的时候,一般浏览器就已经支持ES6了,所以比较喜欢使用ES6语法,let,=>等,文中代码不是抄书的,都用了ES6。

作用域和闭包

this和对象原型

1. 属性描述符(ES5开始)

获取属性描述符: 

myObject =2etownPropertyDescriptor( myObject,"a" figurable: true

设置属性描述符,被设置的属性可以定义过,也可以未定义过,

myObject ="a"2, configurable:

其中:

writable 决定是否可以修改属性的值,如果设置为 false。修改属性值会静失败(silently Failed),严格模式会报错,TypeError。

configurable 决定属性是否可以配置。很显然,把configurable设置为false是单项的。并且无法撤销。

                  即便属性是 configurable:false,我们还是可以 把 writable 的状态由 true 改为 false,但是无法由 false 改为 true。

                  configurable:false 还会禁止删除这个属性,导致删除失败。

enumerable 控制属性是否会出现在对象的属性枚举中,认为true。for..in 遍历的是可枚举属性

2. 访问描述符

当给一个属性定义 getter、setter 或者两者都有时,这个属性会被定义为“访问描述 符”(和“数据描述符”相对)。对于访问描述符来说,JavaScript 会忽略它们的 value 和 writable 特性,取而代之的是关心 set 和 get(还有 configurable 和 enumerable)特性。

myObject =一个setter 2Object.defineProperty(
myObject,
<span style="color: #008000;">//
<span style="color: #008000;"> 目标对象

'b',<span style="color: #008000;">//
<span style="color: #008000;"> 属性

{ <span style="color: #008000;">//
<span style="color: #008000;"> 描述符
<span style="color: #008000;">//<span style="color: #008000;"> 给 b 设置一个 getter
get: <span style="color: #0000ff;">function<span style="color: #000000;">() {
<span style="color: #0000ff;">return <span style="color: #0000ff;">this.a * 2<span style="color: #000000;">
},<span style="color: #008000;">//<span style="color: #008000;"> 确保 b 会出现在对象的属性列表中
enumerable: <span style="color: #0000ff;">true<span style="color: #000000;">
}
)

console.log(myObject.a) <span style="color: #008000;">//<span style="color: #008000;"> 2
console.log(myObject.b) <span style="color: #008000;">//<span style="color: #008000;"> 4
<span style="color: #000000;">
a = 3<span style="color: #000000;">
b = 5<span style="color: #000000;">

console.log(myObject.a) <span style="color: #008000;">//<span style="color: #008000;"> 2
console.log(myObject.b) <span style="color: #008000;">//<span style="color: #008000;"> 4

getter 和 setter 一般是成对出现,如果只出现一个,会导致 set 不生效 / get 到 undefined。

有个getter和setter,就可以在设置数据的同时,做一些其他的事情了,vue的双向绑定,就是在数据set()里更新dom元素,同时在dom的input事件更新数据,实现双向绑定。代码如下:

display: none;" onclick="cnblogs_code_hide('55a6591e-393b-482d-9f85-60e195b60ded',event)" src="https://www.jb51.cc/res/2019/02-05/22/405b18b4b6584ae338e0f6ecaf736533.gif" alt="">
Meta Document + - +4 获取数据都绑定了哪些 dom 元素 并记录 以便数据更新的时候 同步更新dom </span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;._complie(</span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.$el) console.log(</span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;._binding) Object.keys(</span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.$data).forEach((item) </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=></span><span style="background-color: #f5f5f5; color: #000000;"&gt; { </span><span style="background-color: #f5f5f5; color: #008000;"&gt;//</span><span style="background-color: #f5f5f5; color: #008000;"&gt; 这里对value的使用是<a href="https://www.jb51.cc/tag/yige/" target="_blank" class="keywords">一个</a>闭包?...</span>

<span style="background-color: #f5f5f5; color: #000000;"> let value <span style="background-color: #f5f5f5; color: #000000;">= <span style="background-color: #f5f5f5; color: #0000ff;">this<span style="background-color: #f5f5f5; color: #000000;">.$data[item]
Object.defineProperty(<span style="background-color: #f5f5f5; color: #0000ff;">this<span style="background-color: #f5f5f5; color: #000000;">.$data,item,{
get: () <span style="background-color: #f5f5f5; color: #000000;">=><span style="background-color: #f5f5f5; color: #000000;"> {
console.log(<a href="https://www.jb51.cc/tag/huoqu/" target="_blank" class="keywords">获取</a>${item}: ${value})
<span style="background-color: #f5f5f5; color: #0000ff;">return<span style="background-color: #f5f5f5; color: #000000;"> value
},set: (val) <span style="background-color: #f5f5f5; color: #000000;">=><span style="background-color: #f5f5f5; color: #000000;"> {
<span style="background-color: #f5f5f5; color: #008000;">//<span style="background-color: #f5f5f5; color: #008000;"> 更新 data 的时候要把相关 dom 节点全部更新
<span style="background-color: #f5f5f5; color: #000000;"> console.log(更新${item}: ${val})
<span style="background-color: #f5f5f5; color: #0000ff;">if<span style="background-color: #f5f5f5; color: #000000;"> (val <span style="background-color: #f5f5f5; color: #000000;">!==<span style="background-color: #f5f5f5; color: #000000;"> value) {
value <span style="background-color: #f5f5f5; color: #000000;">=<span style="background-color: #f5f5f5; color: #000000;"> val
<span style="background-color: #f5f5f5; color: #0000ff;">this<span style="background-color: #f5f5f5; color: #000000;">._binding[item].forEach((meth) <span style="background-color: #f5f5f5; color: #000000;">=><span style="background-color: #f5f5f5; color: #000000;"> {
meth()
})
}
}
})
})

    }

    </span><span style="background-color: #f5f5f5; color: #008000;"&gt;/*</span><span style="background-color: #f5f5f5; color: #008000;"&gt;*
     * @p<a href="https://www.jb51.cc/tag/ara/" target="_blank" class="keywords">ara</a>m {HTMLElement} root: vue 绑定的 dom 元素节点
     *</span><span style="background-color: #f5f5f5; color: #008000;"&gt;*/</span><span style="background-color: #f5f5f5; color: #000000;"&gt;
    MyVue.prototype._complie </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span> <span style="background-color: #f5f5f5; color: #0000ff;"&gt;function</span><span style="background-color: #f5f5f5; color: #000000;"&gt;(root) {
        </span><span style="background-color: #f5f5f5; color: #008000;"&gt;//</span><span style="background-color: #f5f5f5; color: #008000;"&gt; 如果有子节点</span>

<span style="background-color: #f5f5f5; color: #000000;"> const nodes <span style="background-color: #f5f5f5; color: #000000;">=<span style="background-color: #f5f5f5; color: #000000;"> root.children
<span style="background-color: #f5f5f5; color: #0000ff;">for<span style="background-color: #f5f5f5; color: #000000;"> (let i <span style="background-color: #f5f5f5; color: #000000;">= <span style="background-color: #f5f5f5; color: #000000;">0<span style="background-color: #f5f5f5; color: #000000;">; i <span style="background-color: #f5f5f5; color: #000000;"><<span style="background-color: #f5f5f5; color: #000000;"> nodes.length; i<span style="background-color: #f5f5f5; color: #000000;">++<span style="background-color: #f5f5f5; color: #000000;">) {
const node <span style="background-color: #f5f5f5; color: #000000;">=<span style="background-color: #f5f5f5; color: #000000;"> nodes[i]
<span style="background-color: #f5f5f5; color: #0000ff;">if<span style="background-color: #f5f5f5; color: #000000;"> (node.children.length) {
<span style="background-color: #f5f5f5; color: #0000ff;">this<span style="background-color: #f5f5f5; color: #000000;">._complie(node)
}

            </span><span style="background-color: #f5f5f5; color: #008000;"&gt;//</span><span style="background-color: #f5f5f5; color: #008000;"&gt; 如果是bind 证明绑定了某个数据 那么改数据更改时 更改该处 dom</span>
            <span style="background-color: #f5f5f5; color: #0000ff;"&gt;if</span><span style="background-color: #f5f5f5; color: #000000;"&gt; (node.hasAttribute(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;v-bind</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;)) {
                const d<a href="https://www.jb51.cc/tag/atan/" target="_blank" class="keywords">atan</a>ame </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span><span style="background-color: #f5f5f5; color: #000000;"&gt; node.getAttribute(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;v-bind</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;)
                const attr </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span><span style="background-color: #f5f5f5; color: #000000;"&gt; (node.tagName </span><span style="background-color: #f5f5f5; color: #000000;"&gt;==</span> <span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;INPUT</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span> <span style="background-color: #f5f5f5; color: #000000;"&gt;||</span><span style="background-color: #f5f5f5; color: #000000;"&gt; node.tagName </span><span style="background-color: #f5f5f5; color: #000000;"&gt;==</span> <span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;TEXTAREA</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;) </span><span style="background-color: #f5f5f5; color: #000000;"&gt;?</span> <span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;value</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt; : </span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;innerHTML</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;
                node[attr] </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span> <span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.$data[d<a href="https://www.jb51.cc/tag/atan/" target="_blank" class="keywords">atan</a>ame] </span><span style="background-color: #f5f5f5; color: #008000;"&gt;//</span><span style="background-color: #f5f5f5; color: #008000;"&gt; 初始化<a href="https://www.jb51.cc/tag/yemian/" target="_blank" class="keywords">页面</a></span>
                <span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;._binding[d<a href="https://www.jb51.cc/tag/atan/" target="_blank" class="keywords">atan</a>ame].push(() </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=></span><span style="background-color: #f5f5f5; color: #000000;"&gt; {
                    console.log(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;v-bind: </span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;,node,attr,d<a href="https://www.jb51.cc/tag/atan/" target="_blank" class="keywords">atan</a>ame)
                    node[attr] </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span> <span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.$data[d<a href="https://www.jb51.cc/tag/atan/" target="_blank" class="keywords">atan</a>ame]
                })
            }

            </span><span style="background-color: #f5f5f5; color: #008000;"&gt;//</span><span style="background-color: #f5f5f5; color: #008000;"&gt; 如果有 v-click 就在点击事件中执行methods中对应的那个<a href="https://www.jb51.cc/tag/hanshu/" target="_blank" class="keywords">函数</a></span>
            <span style="background-color: #f5f5f5; color: #0000ff;"&gt;if</span><span style="background-color: #f5f5f5; color: #000000;"&gt; (node.hasAttribute(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;v-click</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;)) {
                const methName </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span><span style="background-color: #f5f5f5; color: #000000;"&gt; node.getAttribute(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;v-click</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;)
                const method </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span> <span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.$methods[methName]
                node.onclick </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span><span style="background-color: #f5f5f5; color: #000000;"&gt; method.bind(</span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.$data) </span><span style="background-color: #f5f5f5; color: #008000;"&gt;//</span><span style="background-color: #f5f5f5; color: #008000;"&gt; method是对data中的数据进行操作,这里记得要把this绑到data上</span>

<span style="background-color: #f5f5f5; color: #000000;"> }

            </span><span style="background-color: #f5f5f5; color: #008000;"&gt;//</span><span style="background-color: #f5f5f5; color: #008000;"&gt; 数据更改时更新 dom 节点 dom 节点更改时也更新 data</span>
            <span style="background-color: #f5f5f5; color: #0000ff;"&gt;if</span><span style="background-color: #f5f5f5; color: #000000;"&gt; (node.hasAttribute(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;v-model</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;)) {
                const d<a href="https://www.jb51.cc/tag/atan/" target="_blank" class="keywords">atan</a>ame </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span><span style="background-color: #f5f5f5; color: #000000;"&gt; node.getAttribute(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;v-model</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;)
                node.value </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span> <span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.$data[d<a href="https://www.jb51.cc/tag/atan/" target="_blank" class="keywords">atan</a>ame] </span><span style="background-color: #f5f5f5; color: #008000;"&gt;//</span><span style="background-color: #f5f5f5; color: #008000;"&gt; 初始化<a href="https://www.jb51.cc/tag/yemian/" target="_blank" class="keywords">页面</a></span>
                <span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;._binding[d<a href="https://www.jb51.cc/tag/atan/" target="_blank" class="keywords">atan</a>ame].push(() </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=></span><span style="background-color: #f5f5f5; color: #000000;"&gt; {
                    node.value </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span> <span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.$data[d<a href="https://www.jb51.cc/tag/atan/" target="_blank" class="keywords">atan</a>ame]
                })

                node.addEventListener(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;input</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;,() </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=></span><span style="background-color: #f5f5f5; color: #000000;"&gt; {
                    console.log(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;v-model</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;,node)
                    </span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.$data[d<a href="https://www.jb51.cc/tag/atan/" target="_blank" class="keywords">atan</a>ame] </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span><span style="background-color: #f5f5f5; color: #000000;"&gt; node.value
                })
            }

        }

    }

    window.onload </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span> <span style="background-color: #f5f5f5; color: #0000ff;"&gt;function</span><span style="background-color: #f5f5f5; color: #000000;"&gt;() {
        const app </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span> <span style="background-color: #f5f5f5; color: #0000ff;"&gt;new</span><span style="background-color: #f5f5f5; color: #000000;"&gt; MyVue({
            el: </span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;#app</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;,data: {
                number: </span><span style="background-color: #f5f5f5; color: #000000;"&gt;0</span><span style="background-color: #f5f5f5; color: #000000;"&gt;,c: </span><span style="background-color: #f5f5f5; color: #000000;"&gt;1</span><span style="background-color: #f5f5f5; color: #000000;"&gt;
            },methods: {
                incre: </span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;function</span><span style="background-color: #f5f5f5; color: #000000;"&gt;() {
                    console.log(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;incre...</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;,</span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;)
                    </span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.number</span><span style="background-color: #f5f5f5; color: #000000;"&gt;++</span><span style="background-color: #f5f5f5; color: #000000;"&gt;
                },minus: </span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;function</span><span style="background-color: #f5f5f5; color: #000000;"&gt;() {
                    console.log(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;minus...</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;,</span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;)
                    </span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.number</span><span style="background-color: #f5f5f5; color: #000000;"&gt;--</span><span style="background-color: #f5f5f5; color: #000000;"&gt;
                },incre4: </span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;function</span><span style="background-color: #f5f5f5; color: #000000;"&gt;() {
                    console.log(</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;incre4...</span><span style="background-color: #f5f5f5; color: #000000;"&gt;'</span><span style="background-color: #f5f5f5; color: #000000;"&gt;,</span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;)
                    </span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.number </span><span style="background-color: #f5f5f5; color: #000000;"&gt;=</span><span style="background-color: #f5f5f5; color: #000000;"&gt; Number(</span><span style="background-color: #f5f5f5; color: #0000ff;"&gt;this</span><span style="background-color: #f5f5f5; color: #000000;"&gt;.number) </span><span style="background-color: #f5f5f5; color: #000000;"&gt;+</span> <span style="background-color: #f5f5f5; color: #000000;"&gt;4</span><span style="background-color: #f5f5f5; color: #000000;"&gt;
                }
            }
        })

    }
</span><span style="color: #0000ff;"&gt;</</span><span style="color: #800000;"&gt;script</span><span style="color: #0000ff;"&gt;></span>

<span style="color: #0000ff;"></<span style="color: #800000;">body<span style="color: #0000ff;">>
<span style="color: #0000ff;"></<span style="color: #800000;">html<span style="color: #0000ff;">>

详见:https://juejin.im/post/5acc17cb51882555745a03f8

 

<div class="page" title="Page 129">
<div class="layoutArea">
<div class="column">
<div class="page" title="Page 132">
<div class="layoutArea">
<div class="column">
<h2 class="p1">3. call、apply、bind 的联系和区别

他们都是定义在Function.prototype里面的函数,都有绑定this的功能。原型如下:

call(thisArg: any,args...: any)

apply(thisArg: any,argArray: Array)

apply可以把存放参数数组直接传递,如果参数存在一个数组里,使用apply将很方面。

可以通过call来将某个对象的函数应用在其他对象:  

bind也可以绑定this,并返回一个函数,同时bind还有一个功能,就是绑定传入的函数

'hello,i am ' + name = 'global'<span style="color: #000000;">

let p1 = { name: 'xiaoming'<span style="color: #000000;"> }
let p2 = { name: 'hanmeimei'<span style="color: #000000;"> }

sayHello('arg1','arg2') <span style="color: #008000;">//<span style="color: #008000;"> i am global
sayHello.apply(p1,['apply1','apply2']) <span style="color: #008000;">//<span style="color: #008000;"> i am xiaoming
sayHello.apply(p2,'apply2']) <span style="color: #008000;">//<span style="color: #008000;"> i am hanmeimei
sayHello.call(p1,'call1','call2') <span style="color: #008000;">//<span style="color: #008000;"> i am xiaoming
sayHello.call(p2,'call2') <span style="color: #008000;">//<span style="color: #008000;"> i am hanmeimei
<span style="color: #000000;">
let sayHelloWithBind = sayHello.bind(p1,'参数1'<span style="color: #000000;">)

sayHelloWithBind('参数2') <span style="color: #008000;">//<span style="color: #008000;"> 参数1 参数2 hello,i am xiaoming

如果使用内置的 .bind(..) 函数生成一个硬绑定函数的话, 该函数是没有 .prototype 属性的。在这样的函数上使用 instanceof 的话, 目标函数的 .prototype 会代替硬绑定函数的 .prototype。

== Foo) console.log(a Bar)

4. import和export

有点多,不想写了。。。。参考 

JavaScript没有构造函数,只有函数的构造调用

JavaScript没有类,只有对象

了解一下随意的

a = === Foo;

constructor,所谓的“构造函数”,其实是Foo.prototype的,a本身并没有这个属性  

也就是说  而和a是怎么生成的没有什么关系。

如果先设置  那么  a = Foo(); 生成的a对象的constructor也就是Object。

a在new的时候,关联到了Foo.prototype,如果你修改了    a所关联的对象是不变的。

<div class="page" title="Page 168">
<div class="layoutArea">
<div class="column">

.constructor 并不是一个不可变属性。它是不可枚举的,但是它的值是可写的。此外,你可以给任意 [[Prototype]] 链中的任意对象添加一个名 为 constructor 的属性或者对其进行修改,你可以任意对其赋值。

综上,.constructor 是一个非常不可靠并且不安全的引用。通常来说要尽量避免使用这些引用。

原型继承

.name =Foo.prototype.myName = <span style="color: #0000ff;">function<span style="color: #000000;">() {
<span style="color: #0000ff;">return
<span style="color: #0000ff;">this<span style="color: #000000;">.name
}

<span style="color: #0000ff;">function<span style="color: #000000;"> Bar(name,label) {
Foo.call(<span style="color: #0000ff;">this<span style="color: #000000;">,name)
<span style="color: #0000ff;">this.label =<span style="color: #000000;"> label
}

<span style="color: #008000;">//<span style="color: #008000;"> 为 Bar.prototype 从新赋值一个 [[Prototype]] 为 Foo.prototype 的对象<span style="color: #008000;">
//<span style="color: #008000;"> 此时 Bar.prototype 是 没有constructor 属性
Bar.prototype =<span style="color: #000000;"> Object.create(Foo.prototype)

Bar.prototype.myLabel = <span style="color: #0000ff;">function<span style="color: #000000;">() {
<span style="color: #0000ff;">return <span style="color: #0000ff;">this<span style="color: #000000;">.label
}

<span style="color: #0000ff;">var a = <span style="color: #0000ff;">new Bar('a','obj a'<span style="color: #000000;">)

console.log(a.myName())
console.log(a.myLabel())

我们来对比一下两种把 Bar.prototype 关联到 Foo.prototype 的方法:

默认的 Bar.prototype Bar.ptototype =修改现有的 Bar.prototype Object.setPrototypeOf( Bar.prototype,Foo.prototype )

JavaScript中没有类,只有对象,所以没有类继承,只有对象的委托,通过 b=Object.create(a) 可以将 b 的[[Prototype]] 属性设为 a,这样当在b中查找属性找不到的时候就可以找到a。a中查找不到就继续沿原型链查找。最终一般会查找到Object.prototype。认字面量对象的[[Prototype]]是Object.prototype。这样,只要在Object.prototype上定义一些函数toString(), valueOf()等,所有对象都可以使用。

new Foo() 操作可以生成一个对象,然后将对象的[[Prototype]] 绑定到Foo.prototype,并将Foo的this绑定为这个新函数,如果Foo()没有返回值的话,该函数将作为返回值。可以看出new像是一个辅助功能,来方面在JS中模拟类似类的操作。注意,如果Foo返回了一个对象,那个new返回的也就是那个对象,新生成的对象将被抛弃。而那个对象,可能和Foo没有任何关系。

对象关联(OLOO, objects linked to other objects)

Task =.id = XYZ == .label == '123','Task-xyz'

在上面的代码中,id 和 label 数据成员都是直接存储在 XYZ 上;在委托行为中我们会尽量避免在 [[Prototype]] 链的不同级别中使用相同的命名,否则就需要使用笨拙并且脆弱的语法来消除引用歧义。你无法在两个或两个以上互相(双向)委托的对象之间创建循环委托。

其实对象关联的风格更容易理解,而原型模式反而像是为了“模拟类”而出现的风格。直接通过new操作符来执行函数内容,同时将对象的原型链接函数的prototype。instanceof 专门用来检查通过这个方法创建对象后两这的关联。

理解了这本书讲的内容,其实这张图也不是很难看懂……

 

<div class="cnblogs_code">

Function.prototype = Function.__proto__ == Function.__proto__.__proto__ = Object.__proto__.__proto__ =Object.prototype.proto = <span style="color: #0000ff;">null <span style="color: #008000;">//<span style="color: #008000;"> Object.prototype 是对象
<span style="color: #000000;">
Function.prototype.prototype = undefined <span style="color: #008000;">//<span style="color: #008000;"> Function.prototype 是函数

相关文章

显卡天梯图2024最新版,显卡是电脑进行图形处理的重要设备,...
初始化电脑时出现问题怎么办,可以使用win系统的安装介质,连...
todesk远程开机怎么设置,两台电脑要在同一局域网内,然后需...
油猴谷歌插件怎么安装,可以通过谷歌应用商店进行安装,需要...
虚拟内存这个名词想必很多人都听说过,我们在使用电脑的时候...