Javascript 中的this指针(通过function定义的函数中的this指针是动态绑定的,谁调用该函数,this就指向谁)
- 直接定义函数,并且通过函数名调用,则函数体中的this指针为window对象,就算函数是在另外一个函数中定义的
- DOM元素绑定事件,回调函数中的this指向DOM元素
- 通过new FunctionName(args)创建对象,FunctionName函数体中的this指向实例对象
- 通过FunctionName.prototype.func = function(){},函数中的this指向实例对象
修改Javascript中的this指针
- 定义一个函数对象,默认this指向window,调用该函数对象的bind函数,绑定参数,第一个传入的就是函数中this应该绑定哪个对象,这样就可以修改了。Fn.bind(obj)则fn中的this就是obj了,fn.bind(obj)会返回新的函数对象,所以应该let newFn = Fn.bind(obj)
- 在函数执行的使用,不直接通过函数名加上括号调用,而是使用Fn.call(args), 传入参数调用,第一个参数就是this的值,可以指定成我们期望的obj
- Fn.apply(obj, […])功能和Fn.call一样,只不过传递参数的方式不同,第一个参数为this,第二个参数为数组,数据中写入Fn正常调用时的实参
Javascript中的ES5类实现
<script> (function() { function Animal(name, age) { if (new.target === Animal) { throw new Error('Abstract class can not be constructed!') } this.name = name this.age = age }
Animal.prototype.say = function() { console.log('say something') } function Dog(name, age) { Animal.call(this, name, age) } // 类通过prototype对象实现继承 // prototype对象中存放方法,还有一个 __proto__ 对象指向父类的 prototype 对象 // 依次类推, Object.prototype.__proto__ 是 null // dog.say() 调用过程, 查看 dog.__proto__ 对象中是否有 say 函数(其中 dog.__proto__ === Dog.prototype), 如果有就调用,如果没有则看 dog.__proto__.__proto__ 中是否有,依次查找 Dog.prototype.__proto__ = Animal.prototype
Dog.prototype.say = function() { console.log('Woof!') } let dog = new Dog('Lily', 1) console.log(dog) dog.say()
})() </script> |
javascript网页上的模块化实现
<script> // 使用立即执行函数实现局部作用域 (function() { function Animal(name, age) { if (new.target === Animal) { throw new Error('Abstract class can not be constructed!') } this.name = name this.age = age }
Animal.prototype.say = function() { console.log('say something') } function Dog(name, age) { Animal.call(this, name, age) } Dog.prototype.__proto__ = Animal.prototype
Dog.prototype.say = function() { console.log('Woof!') }
// 使用 window.Xxx = xxx 导出模块到全局作用域中 window.Animal = Animal window.Dog = Dog })() </script> |
javascript规范
- Commonjs: NodeJs 社区, 同步
- Amd: 异步
- Es6
Babel
- 作用:将ES6的语法转为ES5的语法
- 安装:`npm install -g babel-cli && npm install -D babel-preset-es2015`
- Babel-cli 是命令行工具
- Babel-preset-es2015 是 es5 到 es6 转换的映射工具
- 配置文件:`.babelrc`
- 内容
{ "presets": "es2015", "plugins": [] } |
文件读取
- `let reader = new FileReader()`
- `reader.readAsDataURL(path)` 读取二进制文件,以base64方式返回,因为异步
- `reader.onload = function(){reader.result}`得到结果
- 应用
- 用户在浏览器上选择某一张图片时,input的type为file会触发onchange事件,这个时候可以再回调函数中进行文件读取,将结果作为预览图进行显示
Ajax原理
- `let xhr = new XMLHttpRequest()`
- `xhr.open('get', url)`
- `xhr.send()`
- `xhr.onload = callback` 接受服务器端响应数据完毕触发
- `xhr.onerror = callback` 网络中断触发
- `xhr获取的响应数据是字符串,如果字符串是json形式的,使用JSON.parse()转为对象`
- 如果要POST请求
- `xhr.setRequestHeader('Content-Type', 'applicatoin/x-www-form-urlencoded')` type也可以是`application/json`
- `xhr.send('name=abc&age=22')`或者`xhr.send(JSON.stringnify({name: 'abc', age: 22}))`
- `xhr.status`获取http状态码
- `xhr.readyState`表示xhr对象状态,如果值为4,表示获取服务器端数据完毕
- 可以通过`xhr.onreadystatechange = callback`处理数据
- 跨域情况
- 涉及到跨域问题时,cookie是不发送的,前端的ajax对象需要设置withCredentials=true,而服务器端也设置响应为Access-Control-Allow-Credentials: true
- JSONP实现跨域
- JSONP利用的就是<script>标签中src可以进行跨域实现的,通过src发送GET请求,src得到服务端响应之后,会立即执行响应回来的javascript代码
- 服务器端返回的必须是一个函数调用,发送给客户端的数据作为函数的参数,例如`res.send('fn({a: "a", b: "b"})')`
- 每当要发送跨域的ajax请求时,通过API动态创建script标签,并将标签追加到页面中即可,处理完请求之后(也就是script.onload执行),再将script标签删除`document.body.removeChild(this)`
- 使用JSONP进行跨域,发送的请求一般格式为`http://ip:port/path?callback=funcName`
- 一般采用jsonp函数对jsonp请求进行封装
FormData对象,可以实现二进制文件上传
- `formData.get(key)`
- `formData.set(key, value)`
- `formData.delete(key)`删除某个field
- `formData.append(key, value)`追加filed