JAVAScript总结

JavaScript基础

es6 = ECMAscript2015
es7 = ECMAscript2016
es8 = ECMAscript2017

JavaScript包含

  • 语言核心:
    ECMAscript like 变量 数组 函数 对象…….
  • DOM 文档对象模型
  • BOM 浏览器模型对象

优先级

(++ — !)> 数学>比较>逻辑>赋值

函数表达式

函数表达式也是定义函数的一种方式 比如

      var sum = function(num1,num2) {
            return num1 + num2;
        }

      等号右边的是一个没有名字的函数(匿名函数)

习题:反转整数

function rev(a) {
            var b = 0;
            while(a) {
                b = b*10 + a%10;
                a = parseInt(a/10);
            }
            return b;
        }
 
        alert(rev(6500)); // 6500  56

作用域链

近水楼台先得月

隐式全局变量

不写var的自动成为全局变量

闭包

定义:

一个函数可以把它内部的语句,和自己声明时所处的作用域一起封装成了一个密闭的环境,我们将这封闭的环境成为闭包。

每个函数都是闭包,每个函数天生能够记忆自己定义时所处的作用域

性质:

每次重新引用函数,那么闭包是全新的。

数组

数组中常用方法

数组的头尾操作

push 插到尾巴上
pop 删除尾巴一个,并返回该元素

unshift 插到头上
shift 在开头删除

数组的合并拆分

合并:
arr = arr.concat(arr2,[“…”]);

截取:
arr2 = arr.slice(1,5);
截取index为1~4的元素组成新数组,不包含5。

arr3 = arr.slice(2);
从角标2开始一直截取到数组末尾

arr4 = arr.slice(-4, -2);
从倒数第4项到倒数第三项,不包括倒数第二项。

arr4 = arr.slice(-4);
从倒数第4项到末尾。

arr4 = arr.slice(4, 2);
产生空数组。

这两方法都不会对原数组产生影响。

数组反转

arr.reverse();

splice: 插入删除替换

arr.splice(3,2,”x”,”y”,”z”);
将arr数组的index为3和4的元素替换为”x”,”y”,”z”。

能插能删能替换,简直全能!

join

在数组元素之间插入某个东西,然后返回一个字符串。

sort

排字母正常;
排数字不正常,因为会先把数字变成字符串再排。

所以,更新一下sort。
自定义一下规则。

arr2.sort(function(a, b){
if(a<b){
return -1;
} else if(a==b){
return 0;
} else {
return 1;
}
});

这样,就可以升序排列数字啦!

结合函数观察闭包

案例一

for(var i=0; i<10; i++) {
arr[i] = function() {
alert(i);
}
}
arr0;//10
arr2;//10
arr5;//10

为什么?

闭包只能说它认识这个i,而i在变化。只是记住这个变量,而不是记住变量的值!i的值以用的时候为准。

案例二

for(var i=0; i<10; i++) {
(function(n) {
arr[n] = function() {
alert(n);
}
})(i);
}

arr0;//0
arr5;//5

为什么?

每一个arr在赋值的时候,它都放在IIFE里面,IIFE天生隔离作用域。每一次循环都相当于在for大域里面建立一个新的IIFE小域,每个小域之间彼此隔离。

字符串

属性

length

方法

charAt()

返回指定位置的字符

concat()

“abc”.concat(“lmn”);

indexOf()

检索字符串
“人人都爱人民币”.indexOf(“人”);//0

lastIndexOf()

“人人都爱人民币”.lastIndexOf(“人”);//4

replace()

替换
“hhhjjjsasjk”.replace(“h”, “1”);
//1hhjjjsasjk

slice()

提取
“人人都爱人民币”.slice(-3, -1);
//“人民”

substr()

截取子串
“abcfhh123”.substr(3,6);
//从下标为3的地方开始截取6个字符

substring()

截取字符串
“abcfhh123”.substring(3,6);
//“fhh”
//从下标为3的地方开始,截取到下标为5的位置

toLowerCase()

toUpperCase()

arguments对象

js没有函数重载!

js在遇到两个函数名一样的情况下,它不管你的参数个数有什么不同,下面的覆盖上面的函数。

实验证明:
每个函数都有一个arguments对象,该对象将来会接受用户传入的所有的实参。

arguments不是数组是类数组,类似于数组,是对象。

arguments涵盖了所有的实参。

用arguments模拟函数重载

arguments.length

IIFE

名词解释:

  • 函数自执行表达式
  • 即时调用函数表达式
  • 函数在定义的时候就想直接调用之

用法

只有表达式才可以用()来执行

(function myfunc() {
alert(“hehe”);
})();//hehe

myfunc();//报错

那么干脆不写函数名字。

标准的形式

(function () {
alert(“hehe”);
})();//hehe

本质是个表达式,有值。

JSDOM


一切皆节点:标签节点、属性节点、文本节点

html最大。

查找元素

document.getElementById()
document.getElementsByTagName()
document.body

使用第二个方法找div会找到多个div,我们想改变第三个div的内容怎么办?
var divs = document.getElementsByTagName(“div”);

divs[2].innerHTML = “今天是最后一天”;
document.getElementsByTagName()结果是个类数组。就算取得的只有一个元素,也要当数组用!

id是区分大小写,但是IE6 7 8不区分

IE7以及较低的版本,表单元素name特效也会被当做id

document.getElementById(“he”)

document属性

document.title 就是tab标题啊!
document.URL 当前文档路径

更改html属性

js可以更改html任何属性,方法有两种:

  1. “.”语法
  • 一般属性原封不动的写
  • 对于元素的class属性,应该使用.className
  • 对于for属性,要写成.htmlFor
  • 对于rowspan,要写成rowSpan
  • 对于colspan ,要写成colSpan
  • 对自定义属性无效
  • 所有的行内样式,.style得到的是一个样式对象,继续通过打点得到的是小样式;
  • 点语法效率要高于后者,除了获取自定义属性之外,一般都用点语法。
  1. setAttribute()和getAttribute()
  • 对自定义属性有效
  • getAttribute(“style”)得到的是字符串;
  • 通过方法获得属性,不需要避讳:类似class变className酱紫。

操作元素样式

元素.style得到所有样式的封装,注意打点只能获得行内式!

js双引号里面,原来css怎么写就怎么写

事件

事件三要素

  • 事件源
    谁身上发生的行为(名词)

  • 什么行为
    比如单击

  • 事件处理程序
    行为发生后怎么处理?

常见的事件

  • onclick 单击
  • onmouseover 鼠标进入
  • onmouseout 鼠标离开
  • ondblclick 鼠标双击
  • onfocus 得到焦点
  • onblur 失去焦点
  • onmousedown
  • onmouseup

window.onload = function(){}

当页面加载完成后再去执行函数里面的东西;

document.getElementsByTagName()允许连续找,连续get。

批量添加事件会产生序号闭包问题,如何解决?

  1. 函数内使用this来代替divs[i];
  2. 或者使用IIFE包裹绑定事件:
    原因是匿名函数天生具有封闭作用域;
  3. 给元素强制添加属性,使用this.index代替i:
for(var i=0; i<divs.length;i++){    divs[i].index = i;
    divs[i].onclick = function(){
        divs[this.index].style.color = "yellow";
}
}

计算后的样式

DOM提供了可靠的api,得到计算后的样式。
W3C指定的标准api,IE9+实现了window.getComputedStyle(),该方法接受一个要进行样式计算的元素,返回值是一个样式对象,该样式对象提供了一个getPropertyValue()方法,帮我们得到特定样式属性的计算样式。

// 获取p元素宽度
       var oP = document.getElementById("box");

       //alert(oP.style.width); 返回空 只能操作行内样式
      var w = window.getComputedStyle(oP).getPropertyValue("width");
       // 或
 var w = getComputedStyle(oP).getPropertyValue("width"); window可以省略
       alert(w);
  • 凡是window对象下的方法或者属性,使用时,window都可以省略!
  • getPropertyValue(“box-size”) 双引号里面的参数要使用css属性,不能写驼峰式名字!
  • 可以不用 getPropertyValue(“box-size”) 这个方法来获得样式属性。直接用[“box-size”]或者[“bosSize”]。此时双引号里面驼峰式命名法和css属性命名法皆可。getComputedStyle(oP)[“属性”]
  • 对于IE6/7/8不兼容getPropertyValue(“box-size”) ,IE6/7/8有自己的一套写法: 元素.currentStyle.属性(驼峰式)
    oP.currentStyle.boxSize
    或者 元素.currentStyle.[“属性”] (可驼可不驼)
    oP.currentStyle[“boxSize”]

总结

尽量用总括号,免得记来记取。

问题:

IE不认识getComputedStyle(oP)

Chrome不认识
currentStyle属性

解决
var oDiv = document.getElementsByTagName(“div”)[0];
if(window.getComputedStyle){
alert(getComputedStyle(oDiv)[“paddingLeft”]);
} else {
alert(oDiv.currentStyle.paddingLeft);
}

自己封装一个函数,函数的功能是求某个元素的属性值

<script type="text/javascript">
    //定义函数
    console.log("正常");
      function fetchComputedStyle(obj,property){
        //用户输入的属性有两种情况
        //驼峰式或者css传统写法
        //高版本下将驼峰式变为css传统属性写法
        if (window.getComputedStyle) {
          property = property.replace(/([A-Z])/g, function(match,$1){
            return "-" + $1.toLowerCase();
          });
          console.log(window.getComputedStyle(obj)[property]);
        } else {
          //低版本下,将css传统写法变成驼峰式
          property = property.replace(/\-([a-z])/g, function(match,$1){
            return $1.toUpperCase();
          });
          console.log(obj.currentStyle[property]);
        }
      }
      var oDiv = document.getElementsByTagName("div")[0];
      fetchComputedStyle(oDiv,"paddingLeft");
    </script>

透明度

IE8及以前的版本不支持opacity,js是通过obj.style.opacity或obj.currentStyle.opacity,返回的依然是opacity值,只要保持opacity与filter设置一样便可!

//不兼容写法
opacity: .2;
//兼容写法
opacity: .2;
filter: alpha(opacity=20);

获取透明度属性

//高版本
getComputedStyle(oDiv)[“opacity”];
//低版本
oDiv.currentStyle.opacity;

offsetLeft属性和offsetTop属性

兼容性非常差
通过oDiv.offsetLeft获取
对于IE9+、Chrome等高级浏览器,某个元素的offsetLeft值,是这个元素的左边框外到自己的offsetParent对象的左边框内的距离。

所以,要想知道元素的offsetLeft值的话,必须先知道元素的offsetParent究竟是谁。

offsetParent:

通过oDiv.offsetParent.className获取

  • 对于IE9+、Chrome等高级浏览器:
    自己祖先元素中,离自己最近的且定位的元素,假如祖先元素都没有定位,那么offsetParent对象便是body。 和自己有没有定位没有关系。

  • IE8:
    和高级浏览器大致一样。自己祖先元素中,离自己最近的且定位的元素。但是多算了一条边框。

  • 对于IE6 7:
  1. 如果自己没有定位属性,那么自己的offsetParent对象就是离自己最近的祖先元素含有width或height的元素;
  2. 如果自己有定位属性,则自己的offsetParent属性就是离自己最近的并且定位的元素。

兼容性解决方案

自定位,父无边。

offsetWidth属性和offsetHeight属性

全线兼容 !
自己的属性,和别的盒子无关。
通过oDiv.offsetWidth获取。

offsetWidth = 左右两侧border + width + 左右padding
offsetHeight = 上下border + height + 上下padding

假如盒子没有宽度,此时所有浏览器会把px当做offsetWidth;
假如盒子没有高度,用文字撑开。

clientWidth属性和clientHeight属性

全线兼容!IE6有点问题。。。
通过oDiv.clientWidth获取。

clientWidth = 左右padding + width

假如盒子没有宽度,此时所有浏览器会把px当做clientWidth;
假如盒子没有高度,用文字撑开。IE6 之clientHeight值是0,其他浏览器都是数字。

运动

定时器

window对象有一个方法setInterval(函数,时间间隔)

setInterval(func,2000ms);//ms不要写
//或
setInterval(“func()”,2000ms);//ms不要写
//或
setInterval(func(){},2000ms);//ms不要写

取消定时器

clearInterval(timer);
其中timer是定时器的引用,是个全局变量,创建定时器时曾赋值给这个变量。

运动需要注意的地方

btn_start.onclick = function(){
    timer = setInterval( function(){
        num += 4;
        box.style.left = num + “px”;
    }, 30);
}

连续点击按钮多次,物体运动越来越快,为什么?

因为有多个定时器在起作用,效果叠加。

如何解决?

先取消原来存在的定时器,然后重新开启。like this:

btn_start.onclick = function(){
    clearInterval(timer);
    timer = setInterval( function(){
        num += 4;
        box.style.left = num + “px”;
    }, 30);
}

技巧

拉终停表,让盒子达到希望的位置后停止。

如何制作无缝滚动条?

使用【戏法】- 偷天换日!

JSON

JavaScript object notation
js对象表示法
由JavaScript界大神:道格拉斯自创

json语法

{
“k”:v,
“k”:v,
“k”:v
}

如何使用?

  1. 点语法;
  2. 中括号里面加双引号

json还可以嵌套

感觉跟使用对象差不多!

json还可以添加或者删除属性

person.hobby = [“teaching”, “coding”, “reading”];
alert(person.hobby[1];//teaching

delete person.wife;

json的循环遍历

for(var k in person){
    alert(k);
}

引入外部js要注意的问题

  1. 先引包,再调用;
  2. 如果要先用后引包,则须得将调用函数放到window.onload = function(){}表示窗口加载完毕再执行。

异步和回调函数

同步

js如果没有特殊结构,一般是同步的,前面的语句执行完了之后再执行后面的语句。

异步

js如若遇到特殊结构,(setInterval、setTimeout、ajax、node、事件绑定),不必傻等,继续后面的操作。

apply和call

函数可以通过apply和call语句来指定内部的this指向。

function  fn(){
    console.log(this);
    console.log(this.innerHTML);
}
fn.call(oDiv[0]);

call作用

  1. 可以调用函数;
  2. 改变函数内部this的指向为小括号里面的参数;

apply作用

fn.apply(oDiv[0]);作用和call一样!

两者区别

传参方式不同

function  fn(x,y,z){
    console.log(x+y+z);
    console.log(this);
}
fn.call(oDiv[0],2,3,4);
fn.apply(oDiv[0],[2,3,4]);

setTimeout

只执行一次。

函数节流

函数有时候会设置给一些事件,事件可能被频繁的调用,函数会在短时间内执行多次,就可能会影响其他函数执行

JavaScript高级

面向对象

什么是对象

有狭义广义之分

狭义对象

指的是用花括号{}定义的对象,键值对,它是一组无序的属性集合。

数组也可以存储一组数据,但是不能更好的表达语义。

广义对象

万物皆为对象。

  1. 正则表达式、函数、DOM、数组、window、document、Math、Date、Number、String都是对象
  2. 基本类型不是对象

对象和json的区别

  • json一定是对象,而对象不一定是json
  • 对象中如若键名不符合命名规范,那么就必须要加双引号,访问该属性时也必须使用[“”]形式,不能用点语法
  • js中[]能将变量转化为字符串

对象的方法

假如某个对象的某个属性是一个函数,我们把这个属性成为这个对象的方法。

函数上下文

  1. 当一个函数被当做对象的方法被调用时:obj.fuc(),这个函数里的this指的就是该对象。
  2. var fn = obj.fuc; fn();此时,this == window。

总结

  1. 函数上下文是什么,取决于函数如何被调用,而不是函数如何定义;
  2. 函数直接圆括号调用,上下文就是window;
  3. 当一个函数被当做对象的方法被调用时,这个函数的上下文就是该对象;
  4. 如果函数是事件处理函数,上下文就是触发了这个事件的对象;
  5. 定时器调用函数,上下文就是window;
  6. 数组存放的函数,被数组索引之后加圆括号调用,上下文就是该数组。

callee是什么

function fn(){
alert(arguments.callee === fn);//true
alert(arguments.callee.length);//形参个数
alert(arguments.length);//实参个数
}

new

作用

  • 调用函数
  • 构造函数,返回一个对象:
  1. 在真正执行函数体之前,函数内部先默认创建一个局部变量,是一个空对象;
  2. 让函数体内部的this指向这个空对象,而不是window;
  3. 执行函数体;
  4. 函数体全部执行完毕,函数会返回该对象,返回函数上下文。

构造函数首字母一般大写!
构造函数里面使用return:

  1. 如果返回基本类型,则无视这个return,该return谁就return谁,但是return会阻止这个函数;
  2. 如果return一个引用类型的话,如{}、[]、正则、函数、DOM、Math等,则会覆盖原有,构造出来的对象以你返回的为主。

原型链

定义

所有的构造函数都有一个属性prototype,它指向的是构造函数的原型。当你使用构造函数new出一个实例的时候,这个实例会有一个属性_proto_,它指向的是构造函数的prototype,就是指向所谓的自己原型对象。

三角关系

构造函数的prototype指向谁,new出来的对象的__proto__就指向谁

原理

  • 将来可以被构造函数new出来的实例对象访问。
  • 计算机先看实例的构造函数中有没有say方法,假如没有,就会通过自己的__proto__查找构造函数的原型,原型上有say方法就会执行。

  • 方法定义在构造函数.prototype原型上,将来new出来的对象(实例)。__proto__会指向原型对象,就可以用这个方法了,所有对象共用此方法,完全等价。
  • 任何函数天生都有prototype,它是一个空对象。

继承

将父类的prototype赋值给子类的prototype。

for in 能找到对象的所有属性,包括原型链上的。

hasOwnProperty

任何object都能用。因为它定义在Object.prototype上。

它就找对象本身是否有该属性,不去原型链上找。

不能用一看到undefined就判断该属性不存在!有可能该属性的值就是undefined。

instanceOf

访问一个对象原型链上的每个原型对象,假如遍历到的这个原型对象是某个构造函数的prototype,则认为是这个构造函数的实例。

组件化开发

Date

date.getFullYear()
date.getMonth()//从0开始计数,结果加一才是真实月份
date.getDate()//日
date.getDay()//0~6 星期几
date.getHours()
date.getMinutes()
date.getSeconds()
date.getMilliseconds()
Date.parse("2017-08-09")
全部评论

相关推荐

sunroof:是只有第一批需要空白三方吗,我的对接人说不需要,华为可以等解约之类的。
点赞 评论 收藏
分享
一名愚蠢的人类:多少games小鬼留下了羡慕的泪水
投递荣耀等公司10个岗位
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
11-20 19:57
已编辑
某大厂 golang工程师 23.0k*16.0, 2k房补,年终大概率能拿到
点赞 评论 收藏
分享
点赞 1 评论
分享
牛客网
牛客企业服务