js学习笔记十一(类与面向对象 (OO, Object Oriented),this,更好的 ajax 封装)

134 阅读3分钟

-语言自带的数据类型有限, 要表示复杂的数据, 必须有复杂的数据类型,我们可以用对象表示复杂类型

-类, 就是语言提供的自定义数据类型的机制, 也就是自定义对象

例子如下
// 在一些语言中会有 class 关键字来声明 类
// 但是 js 的处理方式并不是 class, 而是下面这种
// 虽然看上去很怪异, 但无非是个套路罢了
//
// Student 是类名, 一般首字母大写(驼峰命名法(搜))
// 类看起来就是一个函数而已
var Student = function(name, height) {
    // 用 this.变量名 来创造一个只有类的实例才能访问的变量
    this.name = name
    this.height = height
}

使用方式如下
// 用 new 函数名(参数) 初始化一个类的实例
// 赋值给 s1
// 这时候 s1 引用的是一个 Student 类型(也就是对象 Student 的实例)
// 也称之为 对象
var s1 = new Student('gua', 169)

// 可以通过 . 语法访问对象的属性(也就是函数中
// 用 this.变量名 创造的变量)
// 类的变量叫做 属性(单纯只是叫法不同)
log('class, s1', s1.name, s1.height)

// 可以改变 s1 的属性
s1.name = 'xiaogua'
s1.height = 1.69
log('class, s1 属性', s1.name, s1.height)
// 输出如下
// class, s1 属性 xiaogua 1.69

// 可以创建多个互相独立的实例
var s2 = new Student()
var s3 = new Student()
s2.name = 'gau II'
s3.name = '三代瓜'
log(s2.name, s3.name)

// 可以给类增加一些方法(函数)
// 给类定义方法(想想标准库中 String 类的 length )
// prototype 在这里是一个套路, 上课会解释
Student.prototype.greeting = function() {
    console.log(`hello, I'm ${this.name}`)
}

Student.prototype.update = function(name, age) {
    this.name = name
    this.age = age
}

// 可以调用实例的方法
s1.greeting()

// 调用 update 方法
s1.update('xiao', 169.98)
// 实际上相当于
// Student.update(s1, 'xiao', 169.98)

s1.greeting()

-封装, 上面 greeting 和 update 就是封装的例子,意思是说把一些操作做好, 对外部来说只需要简单调用即可

-类主要的优势是:可批量制造 object 和 可封装方法

var ajax = function(method, path, data, reseponseCallback) {
    var r = new XMLHttpRequest()
    // 设置请求方法和请求地址
    r.open(method, path, true)
    // 设置发送的数据的格式
    r.setRequestHeader('Content-Type', 'application/json')
    // 注册响应函数
    r.onreadystatechange = function() {
        if(r.readyState === 4) {
            reseponseCallback(r)
        }
    }
    // 发送请求
    r.send(data)
}


var loadTodos = function() {
    var method = 'GET'
    var path = '/all'
    var url = baseUrl + path
    ajax(method, url, '', function(r){
        var todos = JSON.parse(r.response)
        log(todos)
        insertTodos(todos)
    })
}

var addTodo = function(task) {
    var url = 'http://vip.cocode.cc/sandbox/todo/3400711034/todo'
    var data = {
        'task': task,
    }
    data = JSON.stringify(data)
    ajax('POST', url, data, function(r){
        var t = JSON.parse(r.response)
        console.log(t)
    })
}

var deleteTodo = function(todoId) {
    // var todoId = '965'
    var url = 'http://vip.cocode.cc/sandbox/todo/3400711034/delete/' + todoId
    ajax('GET', url, '', function(r){
        var t = JSON.parse(r.response)
        console.log(t)
    })
}

var updateTodo = function(todoId, task) {
    var url = 'http://vip.cocode.cc/sandbox/todo/3400711034/update/' + todoId
    var data = {
        'task': task,
    }
    data = JSON.stringify(data)
    ajax('POST', url, data, function(r){
        var t = JSON.parse(r.response)
        console.log(t)
    })
}
var Api = function(qq) {
    this.baseUrl = 'http://vip.cocode.cc/sandbox/todo/' + qq
}

Api.prototype.ajax = function(method, path, data, reseponseCallback) {
    var r = new XMLHttpRequest()
    // 设置请求方法和请求地址
    var url = this.baseUrl + path
    r.open(method, url, true)
    // 设置发送的数据的格式
    r.setRequestHeader('Content-Type', 'application/json')
    // 注册响应函数
    r.onreadystatechange = function() {
        if(r.readyState === 4) {
            // console.log('ready state == 4')
            var data = JSON.parse(r.response)
            // console.log('ready state. data', data)
            reseponseCallback(data)
        }
        // console.log('on state change', r)
    }
    // 发送请求
    data = JSON.stringify(data)
    r.send(data)
}

Api.prototype.addTodo = function(task, response) {
    var path = '/add'
    var data = {
        'task': task,
    }
    this.ajax('POST', path, data, response)
}

Api.prototype.updateTodo = function(todoId, task, response) {
    var path = '/update/' + todoId
    var data = {
        'task': task,
    }
    this.ajax('POST', path, data, response)
}

Api.prototype.deleteTodo = function(todoId, response) {
    var path = '/delete/' + todoId
    this.ajax('GET', path, '', response)
}

Api.prototype.loadTodos = function(response) {
    var path = '/all'
    this.ajax('GET', path, '', response)
}

var api = new Api(3400711034)

// api.loadTodos(function(r){
//     console.log('load todos', r)
// })

// api.addTodo('api调用todo', function(r) {
//     console.log('add todo 成功', r)
// })

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>data-* 例子大全</title>
    </head>
    <body>
        <h1>自定义属性</h1>
        <div class=todo-cell data-id=1>
            todo 第一个
            <div>
                <div>
                    <div>
                        <button class=gua-button>更新</button>
                        <button class=gua-button-delete>删除</button>
                    </div>
                </div>
            </div>
        </div>
        <div class=todo-cell data-id=2>
            吃瓜
            <div>
                <button class=gua-button>更新</button>
                <button class=gua-button-delete>删除</button>
            </div>
        </div>
        <script>
            var body = document.querySelector('body')
            body.addEventListener('click', function(event){
                var target = event.target
                if(target.classList.contains('gua-button')) {
                    var dom = target.closest('.todo-cell')
                    var id = dom.dataset.id
                    console.log('click 更新', id)
                }
                if(target.classList.contains('gua-button-delete')) {
                    var dom = target.closest('.todo-cell')
                    var id = dom.dataset.id
                    console.log('click 删除', id)
                }
            })
        </script>
    </body>
</html>