JavaScript
构造函数
function Person(){
//构造函数隐式做了这三步
//var this = {
// __proto__ :Person.prototype
//}
//return this
}
var person = new Person()
原型,原型链,继承,call,apply
原型
Person.prototype.name = 'xiaowu'
Person.prototype = {
lastName : 'wu',
height : 175,
skin : 'yellow',
}
function Person(money,hierarchy){
this.money = money;
this.hierarchy = hierarchy;
}
function Pro(){}
var person = new Person('壹万元','初级')
var person1 = new Person('贰万元','中级')
Person.constructor = Pro //console.log(Person.constructor) --> function Pro(){}
原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承原型的属性和方法。原型也是对象
对象如何查找对象的构造函数 --> constructor
//console.log(Person.constructor) --> function Pro(){}
//var obj = Object.create(原型)
Person.prototype ={
name:"aoxiaoqi",
}
function Person(){}
var person = Object.create(Person.prototype)
//绝大部分的对象最终都会继承自Object.prototype。Object.create(null)是例外
Object.create(null) //Object.create('里面只能放obj和null')
方法重写
var num = 123;
//num.toString();--> new Number(num).toString()
//Number.prototype.toString = functing(){}
//Object.prototype.toString
//Number.prototype.toString
//Array.prototype.toString
//Boolea.prototype.toString
//String.prototype.toString
可正常计算的范围,前16位和后16位
call,apply
call,apply的相同和区别分别是什么
相同的是都是改变this的指向,区别是apply传入列表是数组方式
call 需要把实参按照形参的个数传进去
apply 需要传一个arguments[]
function Person(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
function Student(name,age,sex,tel,grade){
Person.call(this,name,age,sex);
//Person.apply(this,[name,age,sex])
this.tel = tel;
this.grade = grade;
}
var student = new Student('xiaowu',24,'man',177,'primary') //借用构造函数继承
继承
function inherit(Target,Origin){
var F = function(){}
F.prototype = Origin.prototype
Target.prototype = new F()
Target.prototype.constuctor = Target
Target.prototype.uber = Origin.prototype
}
var inherit = (function(){
var F = function(){}
return function(Target,Origin){
F.prototype = Origin.prototype
Target.prototype = new F()
Target.prototype.constuctor = Target
Target.prototype.uber = Origin.prototype
}
})
对象枚举
var obj = {
name:"xiaowu",
age:24,
sex:'man',
height:175,
__proto__:{
lastName:"wu",
}
}
for(var key in obj){
console.log(obj[key]) //xiaowu 24 man 175 wu
}
for(var key in obj){
if(obj.hasOwnProperty(key)){ //obj.hasOwenProperty知道是不是自己的属性还是原型上有的
console.log(obj[key]) //xiaowu 24 man 175
}
}
进制
二进制
1 = 1
10 = 2^1
100 = 2^2
1000 = 2^3
十进制
1 = 1
10 = 10^1
100 = 10^2
1000 = 10^3
十六进制
9 a b c d e f
f = 15
1f = 31
深度拷贝
var obj = {
name : 'abc',
age : '123',
sex : 'man',
card :['visa',"mastar"],
wife:{
name:'bcd',
son:{
name:"aaa",
cc:null,
}
}
}
var obj1 = {}
//遍历对象for(var key in obj)
//判断是不是原始值 typeof() object
//判断是否是数组还是对象 instanceof toString constructor
//建立相应的数组或对象
//递归
function deepClone(origin,target){
var target = target || {}
toStr = Object.prototype.toString
arrStr = "[object Array]"
for(var key in origin ){
// console.log(typeof( origin[key] ))
if(origin.hasOwnProperty(key)){ //避免拿原型上的属性值
if(origin[key] !== null && typeof(origin[key]) == 'object'){//不是null且不是原始值
if(toStr.call(origin[key]) == arrStr){//是数组还是对象
target[key] = []
}else{
target[key] = {}
}
deepClone(origin[key],target[key]) //递归
}else{
target[key] = origin[key]
}
}
}
return target;
}
deepClone(obj,obj1)
简化
function deepClone(origin,target){
var target = target || {}
toStr = Object.prototype.toString
arrStr = "[object Array]"
for(var key in origin ){
// console.log(typeof( origin[key] ))
if(origin.hasOwnProperty(key)){ //避免拿原型上的属性值
if(origin[key] !== null && typeof(origin[key]) == 'object'){//不是null且不是原始值
target[key] = toStr.call(origin[key]) == arrStr ? [] :{}//是数组还是对象
deepClone(origin[key],target[key]) //递归
}else{
target[key] = origin[key]
}
}
}
return target;
}
数组常用方法
改变原数组
push,pop,shift,unshift,sort,erverse
splice
push
var arr = [1,2,3]
arr.push(4,5)//[1,2,3,4,5]
Array.prototype.push = function(){
//for循环因为不知道传进来是多少个数所以使用arguments
for(var i=0; i<arguments.length;i++){
//this是谁调用指向谁所以往最后一位添加东西实现push
this[this.length] = arguments[i]
}
return this.length
}
pop
var arr = [1,2,3]
arr.pop()//[1,2]
Array.prototype.pop = function(){
return this.length = this.length-1
}
shift
var arr = [1,2,3]
arr.shift()//[2,3]
Array.prototype.shift = function(){
for(var i=0; i<this.length;i++){
this[i] = this[i+1]
}
return this.length = this.length-1
}
unshift
sort
var arr = [5,12,13,6,9,1]
arr.sort(function(a,b){//sort 是一种让按照自己定的规则排序里面
return a-b //return a-b 升序 return b-a 降序
})//[1,5,6,9,12,13]
reverse
var arr = [1,2,3]
arr.reverse()//[3,2,1]
Array.prototype.reverse = function(){
var newArr = []
deepClone(this,newArr)//调取的深度拷贝里面的方法
for(var i =0;i<this.length;i++){
this[i] = newArr[newArr.length-i-1]
}
}
splice
var arr = [1,2,3,4,5,6,7,8,9]
//splice(剪切下标,剪切长度,后面无论写多少位都是添加入原数组元素)
//splice(2)只写一位是从下标开始剪切,剪切到数组最后一位//剪切结果[3, 4, 5, 6, 7, 8, 9]//返回数组[1,2]
//splice(2,2) //剪切结果[3,4] //返回数组[1, 2, 5, 6, 7, 8, 9]
//splice(2,2,1,1,3,3) //剪切结果[3,4] //返回数组[1, 2, 1, 1, 3, 3, 5, 6, 7, 8, 9]
不改变原数组
concat,join->split,toString,slice
concat连接两个数组
join->split
var arr = [1,2,3,4,5,6,7,8,9]
arr1 = arr.join(',') //"1,2,3,4,5,6,7,8,9" //按照join('-')里面的分割
arr2 = arr1.split(',')//["1", "2", "3", "4", "5", "6", "7", "8", "9"]
toString
var arr = [1,2,3,4,5,6,7,8,9]
arr1 = arr.toString()//"1,2,3,4,5,6,7,8,9"
slice
var arr = [1,2,3,4,5,6,7,8,9]
arr1 = arr.slice(2,5) // [)左闭右开 arr1 [3,4,5]
arr1 = arr.slice(2) //arr1 [3,4,5,6,7,8,9]
arr1 = arr.slice() // arr1 [1,2,3,4,5,6,7,8,9]
类数组
//属性要为索引(数字)属性,必须要有length属性,最好加上push
//可以利用属性名模拟数组的特性,可以手动添加数组方法
//可以动态增长length属性
//如果强行让类数组调用push方法,则可以根据length属性位置来进行属性扩充
var obj = {
"0" : "a",
"1" : "b",
"2" : "c",
"name" : "wu",
"age" : "12",
"length" : 3,
"push" : Array.prototype.push,
"splice" : Array.prototype.splice,
}
数组去重
Array.prototype.unique = function(){//类数组去重方法
var tymp = {},
newArr = [],
len = this.length;
for(var i = 0;i<len;i++){
if(!tymp[this[i]]){
tymp[this[i]] = 'aa';
newArr.push(this[i])
}
}
return newArr
}
DOM
document Object Model
dom选择器
document.getElementById() //元素id
document.getElementsByTagName() //标签名 []
document.getElementsByName() //标签name []
document.getElementsByClassName() //类名 []
document.querySelector() //css选择器 div>p.strong 缺点不是实时性的
document.querySelectorAll() //css选择器 div>p.strong []
节点
parentNode 父节点(最顶端的ParentNode为document)
childNodes -- 子节点们
firstChild -- 第一个子节点
lastChild -- 最后一个子节点
nextSibliing -- 后一个兄弟节点
previousSibing --前一个兄弟节点
基于元素节点树遍历
parentElement -- 返回当前元素的父元素节点
children -- 只返回当前元素子节点
node.childElementCount === node.children.length 当前元素节点的子节点长度
firstElementChild -- 返回的是第一个元素节点(IE不兼容)
lastElementChild -- 返回的是最后元素节点(IE不兼容)
nextElementSibling/previousEleentSibling --返回后一个/前一个兄弟节点
节点类型
元素节点——1
属性节点——2
文本节点——3
注释节点——8
document——9
DocumentFragment——11
获取节点类型nodeType
节点的四个属性
nodeName
元素标签名,以大写形式表示,只读
nodeValue
text节点或Conment节点的文本内容,可读写
nodeType
该节点的类型,只读
attributes
Element节点的属性集合
Node.hasChildNode()
节点的一个方法.hasChildNode()返回true/false
封装一个children 方法
Element.prototype.myChild = function(){
var childs = this.childNodes //所有的子节点
var len = childs.length
var arr = []
for(var i = 0; i<len; i++){
if( childs[i].nodeType == 1){//nodeType 判断是不是元素节点 == 1
arr.push(childs[i])
}
}
return arr
}
var div = document.getElementsByTagName('div')[0]
JSON,异步加载,时间线
JSON
var obj = {
name:'aoxiaoqi',
age : 17
}
var str = JSON.stringify(obj) // "{"name":"aoxiaoqi","age":17}"
var obj1 = JSON.parse(str) // { name: 'aoxiaoqi', age: 17 }
异步加载
//异步加载文件,需要的时候才调用这些方法
function loadScript(url,callback){
var script = document.createElement('script'); //chuangjian
script.type = 'text/javascript'; //tianjiafangfa
if(script.readyState) {
console.log('b')
script.onreadystatechange = function(){ //IE适用IE
if(script.readyState == 'complete' || script.readyState == 'loaded'){
tools[callback]()
}
}
}else{
script.onload = function(){ //chrome Safari firefox opera
tools[callback]()
}
}
script.src = url;
document.head.appendChild(script)
}
loadScript('load.js',"test")
loadScript('load.js',"demo")
var tools = {
test: function(){
console.log('a')
},
demo:function(){
console.log('b')
}
}
时间线
1、创建Document对象,开始解析web页面。解析HTML元素和他们的文本内容后添加Element对象和Text节点到文档中阶段document.readyState = 'loading'。
2、遇到Jink外部css,创建线程加载,并继续解析文档。
3、遇到script外部js,并且没有设置async、defer, 浏览器加载,并阻塞,等待js加载完成并执行该脚本,然后继续解析4、遇到script外部js, 并且设置有async、defer, 浏览器创建线程加载,并继续解析文档。
对于async属性的脚本,脚本加载完成后立即执行。(异步禁止使用document.write())
5、遇到img等,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档。
6、当文档解析完成,document.readyState = 'interactive'.
7、文档解析完成后,所有设置有defer的脚本会按照顺序执行。(注意 与async的不同,但同样禁止使用document.write(8、document对象触发DOMContentLoaded事件,这也标志着程序执行从同步脚本执行阶段,转化为事件驱动阶段。
9、当所有async的脚本加载完成并执行后、img等加载完成后,document.readyState = 'complete', window对象触事件。
10、从此,以异步响方式外理用户输入网络事件等。
vue公共方法写到原型上的
import commonPlug from '@/common/js/commonPlug' // 所有工具类
import utils from '@/common/js/ycpd_Utils' // 公共方法
import commonApi from '@/api/commonApi'
/*let moment = require('moment')*/
export default {
install(Vue, options) { //Vue 实例 options 配置
Vue.prototype.$commonApi = commonApi
Vue.prototype.$utils = utils
/* Vue.prototype.$moment = moment*/
}
}
Vue.use(commonPlug)