JavaScript Day 1 2019-3-25

基础概念

OOP FP 异步编程 事件循环模型 闭包 MVX 后端编程模型 自动化检查 测试 编译 打包 前后端分离实践

JS语法上不可封装,但技巧上可以封装,使用闭包,Symbol封装。

ES标准
语言定位为:函数式编程的、面向对象的、动态的、事件驱动的、脚本语言(宿主)
Html5 最大特性,对JS开放了硬件接口。
ES数据类型
number boolean string null undefined 基本数据类型,null为对象。
Symbol
Object
只要带原型proto就是对象,唯一特殊的是null没有原型。除基本类型(除null外)都是对象。
判断对象为null,typeof()
ES6才出现的class,也是假的。

API的分布

  1. 全局挂载一部分
  2. 内置函数、对象,两种
  3. 宿主环境上
  4. 第三方库

let People=(function () {

var breath=Symbol('breath')

class Animal{

constructor(){

this.age=0;

        }

walk(){

this[breath]()

console.log("walk...")

}

[breath](){

console.log("breath")

}

}

class Humanextends Animal{

}

return Human

})()

let a=new People()

a.walk()

字面量

123,true, "ddd",'dfss',asdklalds
ksdfa <html> </hmtl> ladal
let as = [1,2,3]
let obj = {id:1, "my-name":'john', sex:true, fav: ['basket'],"my-friend":{....}}
/a+/ig
new RegExp('a+','ig')

对象操作方法

o = new Object()
Object.preventExtensions(o)
/*如果一个对象可以添加新的属性,则这个对象是可扩展的。`Object.preventExtensions()`将对象标记为不再可扩展,因此它将永远不会具有超出它被标记为不可扩展的属性。注意,一般来说,不可扩展对象的属性可能仍然可被删除。尝试将新属性添加到不可扩展对象将静默失败或抛出[`TypeError`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypeError "TypeError(类型错误) 对象用来表示值的类型非预期类型时发生的错误。")(最常见但不排除其他情况,如在[strict mode](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions_and_function_scope/Strict_mode "此页面仍未被本地化, 期待您的翻译!")中)。

`Object.preventExtensions()`仅阻止添加自身的属性。但属性仍然可以添加到对象原型。

一旦使其不可扩展,就无法再对象进行扩展。

*/
Object.seal(o) 
/*
通常,一个对象是[可扩展的](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible "Object.isExtensible() 方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。")(可以添加新的属性)。密封一个对象会让这个对象变的不能添加新属性,且所有已有属性会变的不可配置。属性不可配置的效果就是属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性,或者反之。但属性的值仍然可以修改。尝试删除一个密封对象的属性或者将某个密封对象的属性从数据属性转换成访问器属性,结果会静默失败或抛出[`TypeError`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypeError "TypeError(类型错误) 对象用来表示值的类型非预期类型时发生的错误。")(在[严格模式](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode "如果你想改变你的代码,让其工作在具有限制性JavaScript环境中,请参阅转换成严格模式。") 中最常见的,但不唯一)。不会影响从原型链上继承的属性。

*/
Object.freeze(o)
/*被冻结对象自身的所有属性都不可能以任何方式被修改。任何修改尝试都会失败,无论是静默地还是通过抛出[`TypeError`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypeError "TypeError(类型错误) 对象用来表示值的类型非预期类型时发生的错误。")异常(最常见但不仅限于[strict mode](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Strict_mode "如果你想改变你的代码,让其工作在具有限制性JavaScript环境中,请参阅转换成严格模式。"))。

数据属性的值不可更改,访问器属性(有getter和setter)也同样(但由于是函数调用,给人的错觉是还是可以修改这个属性)。如果一个属性的值是个对象,则这个对象中的属性是可以修改的,除非它也是个冻结对象。数组作为一种对象,被冻结,其元素不能被修改。没有数组元素可以被添加或移除。

这个方法返回传递的对象,而不是创建一个被冻结的副本。

*/

数组的x函数

常用操作
push pop unshift shift slice splice sort reverse
高阶函数
forEach() findIndex() filter() map() reduce every() some()

let as=[3,2,4,9,4,]
as.push(8)
console.log(as)
as.pop()
console.log(as)
as.unshift(6)
console.log(as)
as.shift()
console.log(as)
let rs = as.slice(1,3)
console.log(rs)

as.splice(1,3,11, 34,45)
console.log(as)

let index =  as.indexOf(3)
console.log(index)

let rs1=as.map((item, inx)=>inx%2?item*2:item)
console.log(rs1)
let rs2=as.filter(item=>item>5)
console.log(rs2)

console.log(as)
rs1 = as.reduce((pre,cur)=>pre + cur,10)
console.log(rs1)
rs1 = as.every(item=>item>5)
console.log(rs1)
rs1 = as.some(item=>item>5)
console.log(rs1)

函数

Fuction is algorithm
Fuction is object(is Data)
Fuction is Class(is Contuctor)
Fuction is closure(is program)

函数没有重载概念,因为其也是一个对象,只能根据名字区分,无法根据参数进行区分 。
偏函数 返回的函数
高阶函数 作为参数的函数

闭包

一个函数或对象里面维护了一个局部变量,叫闭包
定义:可以访问外界,但其内部对外界不可见的函数。

function functionFactory(init){
    let x=0;
    function sum(a,b){
        return a+b+init
    }
    return sum;
}

let ss = functionFactory(10)
let ss1 = functionFactory(20)
console.log(ss(2,3))
console.log(ss1(2,3))

console.log("=".repeat(20))

function counterFactory(){
    let value=0
    return function(){
        return ++value;
    }
}

let c1=counterFactory()
for (let i = 0; i <10; i++) {
    console.log(c1())
}

原生 JS 的MV* 模式完成的前端Demo

HTML的部分

···
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="main.js"></script>
</head>
<body>

<div id="app">
<h1> MVVM With raw javascript</h1>

<form id="add-book-form" action="#">
<input type="text" name="name" value="abc">

<input type="number" name="price" value="25.50">

<input type="number" name="count" value="2">

<input type="submit">
</form>
<table id="books-list">
<thead>
<tr>
<th>ID</th>
<th>图书名称</th>
<th>图书价格</th>
<th>图书数量</th>
<th>删除</th>
</tr>
</thead>
<tbody>

</tbody>

</table>
<h3>价格总计: <span></span></h3>
</div>
</body>
</html>
···

JavaScript部分

···
window.onload=function () {
//项目的数据模型
let books=[]

    let app=document.querySelector('#app')
    let url="http://localhost:3000/books"

    /**
     * 完成数据绑定、事件绑定
     */
    function render(){
        let tbody=app.querySelector("#books-list>tbody");
        tbody.innerHTML="";
        books.forEach(book=>{
            let tr=document.createElement("tr")
            tr.appendChild(document.createElement("td")).innerHTML=book.id+"";
            tr.appendChild(document.createElement("td")).innerHTML=book.name+"";
            tr.appendChild(document.createElement("td")).innerHTML=book.price+"";
            tr.appendChild(document.createElement("td")).innerHTML=book.count+"";

            let btn=document.createElement('button');
            btn.innerText="删除"

            btn.addEventListener("click",()=>deleteBook(book))//事件绑定

            tr.appendChild(document.createElement("td")).appendChild(btn)
            tbody.appendChild(tr);

        })
        app.querySelector('#books-list+h3>span').innerHTML=total()+""
    }

    /**
     * 向模型中添加数据
     */
    function addBook() {

        //采集表单数据
        let addBookForm=app.querySelector('#add-book-form')
        let name=addBookForm.querySelector('[name=name]').value.trim();
        let price=parseFloat(addBookForm.querySelector('[name=price]').value.trim())
        let count=parseInt(addBookForm.querySelector('[name=count]').value.trim())
        let book={name:name,price:price,count:count};

        //ajax请求
        fetch(url,{
            method:'POST',
            headers:{'Content-Type':'application/json'},
            body:JSON.stringify(book)
        })
            .then(res=>res.json())
            .then(nb=>{
                books.push(nb)
                render()
            })
    }

    //被绑定的事件,完成从模型中删除数据
    function deleteBook(book) {
        fetch(url+"/"+book.id,{
            method:"DELETE"
        }).then(rs=>{
            let index=books.indexOf(book);
            books.splice(index,1);
            render();
        })
    }

    //总价计算函数
    function total(){
        return books.reduce(function (prev,cur) {
            return prev+cur.price*cur.count;
        },0)
    }

    //立即执行函数,完成初始化的全部工作
    (function(){

        //异步初始化数据,并调用render完成绑定工作
        fetch(url,{
            method:'GET',
        })
            .then(res=>res.json())
            .then(bks=>{
                books=bks
                render()
            })

        app.querySelector('#add-book-form')
            .addEventListener('submit',function (event) {
                addBook();
                event.preventDefault();
            })
    })();
}

···

this指针

this 是在调用时被传入的指针
当作函数直接调用时,它是global对象;当作方法调用时,它是对象本身。
当事件回调时,是事件源本身。
事件回调时,回调函数如果使用Function定义时,this是事件源本身。如果是使用=>定义的,则this是定义的地方的对象。

fn(argv1,argv2)
fn.apply(this,[argv1,argv2])
fn.call(this, argv1,argv2)s

//这样fn的this被绑定到这个this上,也就是=>函数定义函数的真实定义。
let fn1=fn.bind(this)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354