目录
2.4,函数方法call( )&apply( )&bind()
本文内容参考视频:https://www.bilibili.com/video/BV1YW411T7GX?p=124
本教程资料、课件下载地址:https://shimo.im/docs/8RpVGykkWrqvxDyv/read
day one
1.1,JavaScrip—脚本语言
-
特点:解释型语言,面向对象,动态,轻量级脚本语言
-
类型:使用{ }分组,一个{}中的语句一个代码块,共同执行,外部可见
-
执行:从上到下执行逐步执行,一个{}全执行/不执行
-
位置:<script type=”text/javascript” src=“../../js/javascripe”> </script>标签中
1.2,输出
-
页面弹出警告框:window.alert("哥,你真帅啊!!");
-
页面中输内容:document.write(" <br />"<span>"+j+"</span>""); //空格+换行+很多空格 innerHTML
-
控制台输出内容:console.log("你猜我在哪出来呢?");
-
接收用户输入: var score = prompt("请输入小明的期末成绩(0-100):");
1.3,应用举例
-
验证输入:if isNaN(x) { alert("不是数字"); }
-
对事件的反应:<button type="button" οnclick="alert('欢迎!')">点我!</button>
-
改变 HTML 样式:x=document.getElementById("demo"); x.style.color="#ff0000";
-
改变 HTML 内容:x=document.getElementById("demo"); x.innerHTML="Hello JavaScript";
-
直接写入文档输出:<p>xxx</p><script>document.write("<h1>这是一个标题</h1>"); </script><h1>XXX</h1>
1.4,基础了解
-
进制: a = 0x/0/0b10; 16/8/2
-
字面量:恒定的值,注释// /* */,字符“ ” ‘ ’
-
变量声明:var a,b,c; var a=100,b=32,d;
-
转义字符:\\ '\' \n 换行 \t 制表符
-
调用方法:xxx.yyy( ); var a = 123; a=a.toString( );
-
JS编码规则:严格区分大小写,每一条语句以;结尾,忽略多个空格和换行
-
标识符定义:可以自主命名,如变量名,函数名,属性名等
-
标识符组成:字母、数字、_、$组成,不以数字开头,不是关键字和保留字,首小其大,xxxYyyZzz
var foo = "10"+3-"1";console.log(foo); //102
1.5,数据类型
基本数据类型(栈) | ||
---|---|---|
字符串 | String | 单引号,双引号都可,“ d ‘a’ c” var a="aaa"; var b=a[0]; " \" \" " |
数值 | Number | 包括整数和浮点数(小数)var y=123e5; // 12300000 最大 Number.MAX_VALUE,任何值和NaN运算都为空 |
布尔值 | Boolean | true---数值非0/对象 false--0/undefined/null/NAN/空 |
空值 | Null | 定义并赋值,值为null,表示一个为空的对象 ,垃圾回收设a=null |
未定义 | Undefined | 定义但未赋值 NaN 保留字(表明数据类型不是数字) |
对象(引用)类型(堆) | ||
对象 | Object | 引用数据类型 var a={xxx:xxx,xxx:xxx} |
函数 | Function | 一种特别的对象(可执行) var ca=["S","V","C"] |
数组 | Array | 一种特别的对象,下标从0开始 var ca=new Array("S","V"); ca[2]="C" |
判断 | ||
typeof | 检查变量类型 结果:null与array都显示object | console.log ( typeof [1,2,3]); //Object console.log ( typeof null); //Object |
instanceof | 检查对象是否是类的实例 即判断对象的具体类型 | console.log (b1 instanceof Object); |
=== | 数据对象和类型都等 | console.log (typeof a===‘ undefined' ); |
in | 检测属性是否属于该对象 | console.log(“属性名”in 对象); |
isNAN | 检查是否是数字 |
1.6,类型转换
-
隐式转换:var a ='a' b=!!a //true c=false d='a'+c //afalse d='2' e=6/d //3
-
其它—》字符串:a=a.toString( ); // null/undefined不可 a.toString(2); //转换成二进制
-
其它—》字符串:a=String(a);//null/undefined直接原样输出
-
其它—》布尔:b=Boolean(a); //0/NaN/null/undefine/空串---》false
-
其它—》数字:a=Number(a); // true/false/null/空串/undefined/非数字字符串-》 1/0/0/0/NaN/NaN
-
字符串—》数值: parseInt (a,16)/parseFloat(a); 转化成16进制整形,16/10需表明最好不省略
1.7,运算符
分类 | 举例 | 特点 |
---|---|---|
逻辑运算符 | && 与 || 或 ! 非 | 同真/假即真/假,有假/真即假/真,取反,化boolean看 |
关系运算符 | > >= < <= | 一般化化数值比较,任何值和NaN做任何比较都是false 字符串间逐位比较按Unicode编码,返回boolean值 |
相等运算符 | == != === !== | 转换为同类型比较,后二不转换,返回boolean值 |
1.8,流程控制语句
if语句 | 条件分支语句 | while循环 |
---|---|---|
* if(条件表达式) * { * 语句... * }else if { * 语句2... * }else{ * 语句3... * } | * switch(条件表达式){ * case 表达式: * 语句... * break; * case 表达式: * 语句... * break; * default: * 语句... * break; * } | * while(条件表达式){
* do{ |
for循环 | break/continue | |
* for(①初始化表达式;②条件表达式;④更新表达式){ * * break:终止循环 * continue:跳出本次循环
| outer: for(var i=0 ; i<5 ; i++){ console.log("@外层循环"+i) for(var j=0 ; j<5; j++){ break outer; console.log("内层循环:"+j); } } //输出:@外层循环 |
Day two
2.1,对象
-
分类:内建对象(ES标准)/宿主对象(浏览器提供)/自定义对象
-
创建:new调用函数为构造函数(首字母大写),var obj = new Object( ); var obj={ }
-
添加:对象.属性名=属性值 obj2.name = "孙悟空"/obj1 obj2.ca=fun( ){ }; ca为函数名
-
对象["属性名"]=属性值 //属性名含特殊字符/不确定 obj1['co-dj]=a;
-
删除:delete 对象.属性名; delete obj.name;
-
读取:对象.属性名 console.log(obj.name/obj.ca()); //obj.ca--调用对象的属性,返回一个函数字符串
-
循环:for(var i in obj){ } '属性名‘ in 对象 //检查对象中是否含有该属性
-
对象字面量: var obj1={name:"a",id:1,test:{name:"b"},a:function( ){ }}; //a为函数名
2.2,函数 function
-
创建:function 函数名([形参1,形参2...]){ 语句... } function fun2( ){ } //可先调用后写
-
var 函数名 = function([形参1,形参2...]){ 语句... } ; //同变量,不可先调用后写,有;
-
调用:函数名(实参1,实参2...); 任意类型,自检查,多不管,少为undefined
-
用例:function f3 (a,b){console.log(“a=”+a);} var a =f3(1,3);
-
返回值:任意类型/对象/函数,不写return或a默认返回undefined
//立即执行函数:函数定义完,立即被调用,往往只会执行一次
(function(a,b){console.log("a +b= "+a);;})(1,2);
//枚举,obj为定义好含很多内容的对象
for(var n in obj){ //4个属性执行4次
console.log("属性名:"+n);
console.log("属性值:"+obj[n]);
} //每次执行时,会将对象中的一个属性的名字赋值给变量
2.3,作用域:
1.全局作用域 全局对象window调用,任意位置都可访问,不可调用函数变量
2.函数作用域 函数调用时创建,彼此独立,可访问全局变量,报错ReferenceError
定义形参就相当于在函数作用域中声明了变量
//使用var关键字声明的变量,会在函数中所有的代码执行之前被声明
var a=10;
function fun3(){ console.log(a); var a = 35;} //若无,则a=10;
fun3(); //输出:a=undefined
//在函数中,不适用var声明的变量都会成为全局变量
var c = 33;
function fun5(){ console.log("c = "+c); c = 10; d = 100;}
fun5(); //输出:c=33;
console.log("d = "+d); //输出:d=100
2.4,函数方法call( )&apply( )&bind()
让一个函数成为指定对象的方法进行调用 详解 bind返回的是一个函数后有()
function fun(a,b) {
alert(this.name); //使用call和apply调用时,this是指定的那个对象
console.log("a = "+a);
console.log("b = "+b);
}
//fun.apply()=fun.call()=fun();
var obj1 = { name: "obj1" };
var obj2 = { name: "obj2" };
fun.call(obj1); //输出:"obj1"
fun.call(obj2); //输出:"obj2"
//第一个参数的对象,为函数执行时的this
fun.call(obj,2,3); //call()方法可以将实参在对象之后依次传递
fun.apply(obj,[2,3]); //apply()方法需要将实参封装到一个数组中统一传递
2.5,this
-
定义:解析器/浏览器调用函数向内部传递进的一个隐含参数
-
指向:以函数的形式调用时,this永远都是window
-
以方法的形式调用时,this就是调用方法的那个对象
-
以构造函数的形式调用时,this就是新创建的那个对象
-
使用call和apply调用时,this是指定的那个对象
-
在事件的响应函数中,响应函数是给谁绑定的this就是谁
function fun(){
console.log(this.name);
}
var name = "全局的name属性";
var obj = {
name:"孙悟空",
sayName:fun,
id:1
};
fun(); //输出:"全局的name属性"
obj.sayName(); //输出:"孙悟空"
console.log(obj.id); //输出:"1"
2.6,工厂&构造函数&原型:
- 使用工厂方法创建对象:使用的构造函数都是Object,所以创建的对象类型一致,无法区分
function createDog(name , age){
var obj = new Object();
obj.name = name;
obj.age = age;
obj.sayHello = function(){
alert("汪汪~~");
};
return obj;
}
var obj2 = createPerson("猪八戒",28,"男");
var obj3 = createPerson("白骨精",16,"女");
var obj4 = createPerson("蜘蛛精",18,"女");
-
使用构造函数创建对象:function Do ,首字母大写,调用多new var a =new f3(1,3); 类,实例
-
每一个对象都添加了sayName方法,浪费,若在全局作用域中定义,不安全
function Person(name , age , gender){//Person 类
this.name = name; //构造函数的执行流程:
this.age = age; //1.立刻创建一个新的对象
this.gender = gender; //2.将新建的对象设置为函数中this
this.sayName = function(){ //2.在构造函数中可以使用this来引用新建的对象
alert(this.name); //3.逐行执行函数中的代码
}; //4.将新建的对象作为返回值返回
}
function Dog(){ }; //Dog 类
var dog=new Dog; //dog 实例
var per = new Person("孙悟空",18,"男"); //per per2 实例
var per2 = new Person("玉兔精",16,"女");
console.log(per instanceof Person); //检查对象是否是类的实例
console.log(dog instanceof Person); //输出:true false
- 原型:prototype 一个公共的区域,所有同一个类的实例都可以访问到这个原型
//显示原型prototype,隐式原型__prto__ ,对象隐式原型的值==对应构造函数显示原型的值
//原型对象有一个constructor属性,它指向函数对象 即 fun.prototype.constructor===fun ---true
function MyClass(){
}
MyClass.prototype.a = 123; //向MyClass的原型中添加属性a
MyClass.prototype.sayHello = function(){
alert("hello"); //向MyClass的原型中添加一个方法
};
var mc = new MyClass(); //_ _两横,通过proto访问隐含属性
console.log(mc2.__proto__ == MyClass.prototype); //输出:true
console.log(mc2.a); //输出:"123"
mc.a = "我是mc中的a"; //查找属性,先自己,在公共
console.log(mc2.a); //输出:"我是mc中的a"
- 上述改良
//向原型中添加sayName方法
Person.prototype.sayName = function(){
alert("Hello大家好,我是:"+this.name);
};
-
检查对象(原型)是否含有这个属性:console.log(“属性名”in 对象); 返回true/false
-
检查对象自身中是否含有该属性:console.log(mc.hasOwnProperty("age"));
-
原型即对象 也有原型,祖先Object: console.log(mc.__proto__.__proto__.hasOwnProperty("hasOwnProperty"));
day three
3.1,数组(Array,一种对象)
-
创建:var arr = new Array(10,20,30); //一个数字则表示数组长度,对象任意类型
-
var arr = ["hello",1,true,null,undefined]; //使用字面量创建数组
-
添加:数组[索引] = 值 arr[0] = 10; //索引从0开始
-
读取:数组[索引] console.log(arr1[3]==arr2[3]);
-
求长:console.log(arr.length) 值为最大索引+1 arr.length=7 //修改长度为6,多则删
-
修改:arr.length = 10; 多空出,少删除 arr[arr.length] = 70;
-
遍历:for(var i ; i<数组.length;i++){ } 数组.forEach(function(value,index,obj){ });
3.2,原生 js 操作数组方法:
-
unshift():数组开头添加元素,并返回添加后的个数 arr.unshift("12","22");
-
push():数组末尾添加元素,并返回添加后的数组个数
-
pop():删除数组最后一个元素,并返回删除的元素
-
shift();删除数组的第一个元素,并返回删除的元素
-
slice(a,b):提取a~b,不包括b,复制到新数组中,b可省,a=-1表最后一个元素,a=arr.slice(0); //复制arr
-
splice():删除原数组从a开始的b个元素,在插入c arr.splice(3,1,"牛魔王","红孩儿");
-
concat():连接多个数组,返回新数组 var result = arr.concat(arr2,arr3,"王"); //连接arr,arr2,arr3,王
-
join():将数组转换为一个字符串并返回新,若有a则默认作为连接符 arr=[1,2]; a= arr.join("@"); 1@2
-
reverse():反转原数组
-
sort():按Unicode编码排序原数组 arr.sort(function(a,b){ return a - b/b - a; }); //升序/降序排列
-
indexOf(): 查找数组中是否有某项,有的话返回该项的所引,没有话返回-1;
-
toString():把数组转成以逗号分隔的字符串
-
forEach(function(value,index,obj){ },value):循环(元素/索引/数组)
-
filter(function(currentValue,index,arr), thisValue):1必须,其它可选,创建新数组,为符号函数要求的旧数组构成
3.3,Math对象
-
Math.floor(): 向下取整
-
Math.ceil():向上取整
-
Math.random():取0-1之间的随机小数 Math.round(Math.random()*(y-x)+x); //(x,y)之间
-
Math.round():四舍五入取整
-
Math.abs():取绝对值
-
Math.pow(x,y): x的y次幂
-
Math.sqrt():开平方
-
Math.max():取最大值
-
Math.min():取最小值
-
Math.PI:常量,圆周率
3.4,Date日期对象
new Date() | 创建一个日期对象 |
Date() | 将日期转换成字符串 String(new Date()) |
getDate() | 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 //设置用set |
getDay() | 从 Date 对象返回一周中的某一天 (0 ~ 6)。 |
getFullYear() | 从 Date 对象以四位数字返回年份。 |
getHours() | 返回 Date 对象的小时 (0 ~ 23)。 |
getMilliseconds() | 返回 Date 对象的毫秒(0 ~ 999)。 |
getMinutes() | 返回 Date 对象的分钟 (0 ~ 59)。 |
getMonth() | 从 Date 对象返回月份 (0 ~ 11)。 |
getSeconds() | 返回 Date 对象的秒数 (0 ~ 59)。 |
getTime() | 返回 1970 年 1 月 1 日至今的毫秒数。 |
3.5,正则表达式
-
含义:定义字符串的规则,检查字符串是否符合规则,是对象
-
创建:使用字面量:var 变量 = /正则表达式/匹配模式 var reg=a/gi; 方便 i 忽略大小写
-
使用构造函数:var 变量 = new RegExp("正则表达式","匹配模式"); 灵活 g 全局匹配模式
-
检查:var reg = new RegExp("a","g"); var str = "xasd"; console.log(reg.test(str));
-
//输出:true,检查str是否含a,严格区分大小写
-
举例:var phoneReg = /^1[3-9][0-9]{9}$/; //检查手机号,1开头,第2个3-9,9个0-9结尾,若无$则131111111118908对
-
reg = /\bchild\b/; //查找含child独立的单词,前后为空 即 a child live
-
var str=" ss "; str = str.replace(/\s/g , ""); //ss 去除所有空格
-
str = str.replace(/^\s*|\s*$/g,""); //去除开头和结尾的空格,无g则不全局,可能至去除前面的
量词 | |||||
---|---|---|---|---|---|
{n} 正好出现n次 | /a{2}/ | aa | ^ 表示开头 | /^a/ | a... |
/ab{2}/ | abb | $ 表示结尾 | /a$/ | ...a | |
/(ab){2}/ | abab | 混合 | /^a$/ | a | |
{m,n} 出现m-n次 | /a{1,3}/ | a~aaa | 任意 | /a|b|c/=/[ab] | a或b或c |
{m,} m次以上 | /a{1,}/ | a~a... | 全选 | /[a-zA-Z]/ | 任意字母 |
+ 至少一个,同{1,} | /a+b/ | ab~a...b | [a-z] | 任意小写字母 | |
* 0个或多个,同{0,} | /a*b/ | b~a...b | [0-9] | 任意数字 | |
? 0个或1个,同{0,1} | /a?b/ | b/ab | 除了 | [^0-9 ] | 不含数字 |
^(0|[1-9][0-9]*)$ | 只能输入零 | +非零开头数字 | \num | /[a-z]\1/ | 出现重复字母 |
- 转义字符:字面量中\\代表\ 构造函数中\\\\代表\
转义字符 | |||||
\w 任意字母、数字、_ | reg = /\w/; | = / [A-z0-9_] / | \s | 空格 | reg = /\s/; |
\W除了字母、数字、_ | reg = /\W/; | =/ [^A-z0-9_] / | \S | 除了空格 | reg = /\S/; |
\d 任意的数字 [0-9] | reg = /\d/; | =/ [0-9] / | \b | 单词边界 | reg = /\b/; |
\D 除了数字 [0-9] | reg = /\D/; | = / [^0-9] / | \B | 非单词边界 | reg = /\ |
3.6,字符串和正则
replace() | 将字符串中指定内容替换为新的内容,默认只第一个 result = str.replace(/[a-z]/gi , "@_@"); |
match() | 会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果 |
split() | 将一个字符串拆分为一个数组 var str = "1a2cd3"; var result = str.split(/[A-z]/); //输出:1,2, ,3 |
search() | 搜索字符串中是否含有指定内容,有返回索引,无返回-1,默认只第一个 result = str.search(/a[bef]c/); |
3.7,字符串方法
slice() | 将符合条件的内容从字符串提取出来通过数组返回,默认只第一个 result=str.match(/[a-z]/); |
slice() | 提取字符串的片断,并在新的字符串中返回被提取的部分 |
toLower/UpperCase() | 把字符串转换为小/大写 |
trim() | 移除字符串首尾空白 |
last/ IndexOf() | 返回字符串中检索指定字符最后/早一次出现的位置 |
substr() | 从起始索引号提取字符串中指定数目的字符 |
concat() | 连接两个或多个字符串,返回连接后的字符串 |
charAt() | 根据索引获取指定的字符 |
charCodeAt() | 根据索引获取指定的字符编码 |
day four
4.1,DOM文档对象模型
-
定义: Document Object Model (网页 节点 关系)
-
查询:W3Cschool离线手册--》JS--》JavaScript 对象---》HTML对象--》找对应a/...对象属性操作
-
文档节点(document):代表网页,所有节点都是它的子节点,直接使用
-
元素节点(element):
-
document.getElementById/getElementsByTagName/getElementsByName(“ ”);
-
通过id属性/标签名/name获取一个/一组/一组元素节点对象
-
元素节点通过innerHTML获取和设置标签内部的html代码,自结束标签不行,元素.属性名
-
-
文本节点(text):
-
获取元素节点的子节点:通过具体的元素节点调用
-
元素节点.getElementsByTagName(“ ”); //返回当前节点的指定标签名后代节点
-
元素节点.childNodes/firstChild/lastChild //返回当前节点的所有/第一/最后子节点(包括文本节点--标签间的空白)
-
元素节点.children/firstElementChild //返回当前节点的所有/第一/最后子元素
-
文本节点通过nodeValue属性获取和设置文本节点的内容 //alert(bj.firstChild.nodeValue);
-
-
属性节点(attribute):元素节点.getAttributeNode(“属性名”); //一般不使用
4.2,事件:
-
定义:用户和浏览器之间的交互行为,如:点击按钮,移动鼠标,关闭窗口等
-
方法一:<button id="btn" οnmοusemοve="alert('讨厌!');">按钮</button> //结构和行为耦合,不推荐
-
方法二:var btn = document.getElementById("btn");btn.onclick = function(){ alert("你还点~~~"); }; //推荐
//原因:代码由上而下执行,页面未加载,即DOM对象未加载,故无法获取到DOM对象
//解决:为window绑定一个onload事件
<script type="text/javascript">
window.onload = function(){
var btn1 = document.getElementById("btn");
btn1.innerHTML="i am button";//修改按钮文字
btn1.onclick = function(){ //为按钮绑定一个单击响应函数
alert("hello");
};
var btn2= document.getElementById("btn2");
btn02.onclick = function(){
var lis = document.getElementsByTagName("li");
for(var i=0 ; i<lis.length ; i++){
alert(lis[i].innerHTML); //读取元素节点属性
alert(inputs[i].className); //元素.属性名,class用className
} //根据标签名来获取一组元素节点对象,返回一个类数组对象
}; //所有查询到的元素都会封装到对象,哪怕只有一个
}; //或不需window那一行,写在<body>里,标签下
<body>
<input class="hello" type="radio" name="gender" value="male"/>
<div><button id="btn01">查找#bj节点</button></div>
<body/>
事件 | 说明 | 事件 | 说明 | 事件 | 说明 |
---|---|---|---|---|---|
onabort | 图像加载被中断 | onkeypress | 键盘的键被按下 | onreset | 重置按钮被点击 |
onblur | 元素失去焦点 | onkeyup | 键盘的键被松开 | onresize | 调整窗口尺寸 |
onchange | 用户改变域的内容 | onload | 页面/图像完成加载 | onselect | 选定文本 |
onclick | 鼠标点击某个对象 | onmousedown | 鼠标按键按下 | onsubmit | 提交按钮被点击 |
ondblclick | 鼠标双击某个对象 | onmousemove | 鼠标移动 | onunload | 用户退出页面 |
onerror | 加载文档/图像报错 | onmouseout | 鼠标从某元素移开 | onkeydown | 键盘的键被按下 |
onfocus | 元素获得焦点 | onmouseover | 鼠标移到某元素上 | onmouseup | 鼠标按键被松开 |
4.3,DOM查询
-
形式:具体节点.查询方式
-
innerHTML:获取标签内部的html代码 <h>aaa</h>
-
innerText:获取到元素内部的文本内容 aaa
-
parentNode:获取当前节点的父节点
-
previousSibling:获取当前节点的前一个兄弟节点,也可获取空白文本
-
previousElementSibling:获取当前节点的前一个兄弟元素,不可获取空白文本,IE8上用
-
nextSibling:获取当前节点的后一个兄弟节点
-
checked:获取或设置多选框的选中状态 items[i].checked = true;
-
childNodes:获取当前元素的所有子节点,包括空白节点
-
firstElementChild:获取当前元素的第一个子元素
-
children:获取当前元素的所有子元素
-
firstChild:获取当前元素的第一个子节点,会获取到空白的文本子节点
-
lastChild:获取当前元素的最后一个子节点
4.4,DOM对象的其它属性和方法:
-
document.documentElement:获取页面html根标签
-
document.body:获取页面中body的引用
-
document.all:代表页面中所有的元素 =document.getElementsByTagName(“*”);
-
document.getElementsByClassName() :可以根据class属性值获取一组元素节点对象 IE9及以上
-
document.querySelector() :根据css选择器,多个返回唯一的第一个元素 var div = document.querySelector(".box1 div");
-
document.querySelectorAll():封装成数组返回 box1 = document.querySelectorAll(".box1/#box2");
4.5,DOM增删改查
-
document.createElement():创建元素节点
-
document.createAttribute():创建属性节点
-
document.createTextNode():创建文本节点
-
父节点.appendChild(子节点):添加子节点
-
父节点.insertBefore(新节点,旧节点):将一个新的节点插入到旧节点的前边
-
父节点.replaceChild(新节点,旧节点):使用一个新的节点去替换旧节点
-
父节点.removeChild(子节点):删除指定的子节点 =子节点.parentNode.removeChild(子节点)
<script type="text/javascript">
window.onload = function() {
myClick("btn01",function(){
var li = document.createElement("li"); //创建一个"li"节点
var gzText = document.createTextNode("广州"); //创建一个"广州"文本
li.appendChild(gzText); //添加
var city = document.getElementById("city");
var bj = document.getElementById("bj");
city.appendChild(li); //添加到#city后
city.insertBefore(li , bj); //在#beijing前插入
city.replaceChild(li , bj); //用li替换bj
city.removeChild(bj); //父节点.removeChild(子节点);
bj.parentNode.removeChild(bj); //删除一个子节点 bj.parentNode=bj父节点
city.innerHTML += "<li>广州</li>"; //创建新节点广州,简单
var li = document.createElement("li"); //综合,创建新节点
li.innerHTML = "广州"; //综合
city.appendChild(li); //综合
});
function myClick(idStr, fun) {
var btn = document.getElementById(idStr);
btn.onclick = fun;
}
}
4.6,操作内联样式
-
设置:元素.style.样式名 = 样式值 box1.style.width = "300px"; //为内联样式
-
读取:元素.style.样式名 alert(box1.style.width); 只读取内联样式<div id="a" style="width:200px;">
-
alert(box1.currentStyle.width);//获取所有中当前正在生效的样式,若无值,则默认auto 只IE支持
-
alert(getComputedStyle(box1,null).width); //读取元素的当前样式,若无值,则长度..px 不支持IE8及以下
-
驼峰:box1.style.backgroundColor = "yellow"; //有-,去-,后大写
-
备注:有!important,JS修改样式失效
-
查找:不会改 W3School---->CSS--->CSS参考手册 如背景 点击border Java Script 语法
function getStyle(obj , name){ //定义一个函数,用来获取指定元素的当前的样式
if(window.getComputedStyle){ //加window,变量的属性,没有返回未定义,而不是报错
return getComputedStyle(obj , null)[name]; //正常浏览器的方式
}else{
return obj.currentStyle[name]; //IE8的方式
}
}
4.7,其他样式相关的属性:
查找:不会改 W3School---->HTML DOM--->DOM参考--> HTML DOM对象---->DOM Element
-
offsetWidth/Height:获取元素的可见宽度和高度,返回不带px的数字=内容区+内边距,只读
-
offsetWidth/Height:获取元素的整个的宽度和高度,返回不带px的数字=内容区+内边距+边框
-
offsetParent:获取离当前元素最近的开启了定位的祖先元素,若无,则返回body
-
offsetLeft/Top:获取当前元素相对于其定位父元素的水平/垂直偏移量
-
scrollWidth/Height:获取元素整个滚动区域的宽度和高度
-
scrollLeft/Top:获取垂直滚动条滚动的距离
-
clientX/Y:获取鼠标指针的水平/垂直坐标
-
disabled:属性可以设置一个元素是否禁用,如果设置为true,则元素禁用
获取滚动区域的高度:alert(box4.scrollHeight - box4.scrollTop); ==?clientHeight
4.8,事件对象:DOM Event
-
定义:事件的响应函数被触发,浏览器将一个事件对象作为实参传递进响应函数,在其中封装了当前事件相关的一切信息
-
比如:鼠标的坐标 键盘哪个按键被按下 鼠标滚轮滚动的方向。。。
-
onmousemove - 该事件将会在鼠标在元素中移动时被触发 查看:dom event 处
-
box1.onclick = function(event){ } //为box1绑定一个单击响应函数,若document则全局绑定
-
event = event || window.event; //解决事件对象的兼容性问题
-
var st = document.body.scrollTop || document.documentElement.scrollTop; //谷歌/火狐 兼容性
-
-
事件的冒泡:事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
-
取消事件对象的冒泡:event.cancelBubble = true; //开发中大多冒泡都有用
-
事件的委派: 指将事件统一绑定给元素的共同的祖先元素,当后代元素上的事件触发时,
-
会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件
-
事件的绑定:使用 对象.事件 = 函数 的形式绑定响应函数,多个后覆盖前,以下可同时绑定多个
btn01.addEventListener("click",function(){ alert(1);},false); //IE8及以下不支持,this绑定对象
btn01.attachEvent("onclick",function(){ alert(2); }); //后绑定先执行,this指window
先捕获,后冒泡 捕获由外向内,冒泡由内向外
function bind(obj , eventStr , callback){ //obj 要绑定事件的对象
if(obj.addEventListener){
obj.addEventListener(eventStr , callback , false);
}else{
obj.attachEvent("on"+eventStr , function(){ //eventStr 事件的字符串(不要on)
callback.call(obj); callback 回调函数
});
}
} //事件的绑定,兼容所有浏览器
//如果触发事件的对象是我们期望的元素,则执行否则不执行
if(event.target.className == "link"){
alert("我是ul的单击响应函数");
}
day five
5.1,BOM
-
定义:浏览器对象模型(browser object model)
-
BOM对象:Window/Navigator/Location/History/Screen 窗口/信息/地址栏信息/历史/屏幕
-
Navigator:识别不同的浏览器
-
History:back/forward/go() //跳转到上一个/下一个/指定页面
5.2,JSON
-
定义:JS对象表示法(JavaScript Object Notation)
-
类型:数组[ ]或对象{ }(正则/日期对象,函数除外),是一种特殊格式的字符串
-
内容:字符串(“ ”)、数值(必须以十进制表示)、布尔值和
null
(不能使用NaN
,Infinity
,-Infinity
和undefined
) -
转换:var o = JSON.parse(json); //将JSON字符串转换为js对象 var str = JSON.stringify(obj3); //反向
day six
6.1,栈&堆
//值保持在栈内,彼此独立互不影响,对象保存在堆内,用指向表示,对象比较地址
var obj = new Object(); var a = 123; var a=2;
obj.name = "孙悟空"; var b = a; function fn(a){
var obj2 = obj; a++; a=a+1;
obj.name = "猪八戒"; console.log("a = "+a); }
console.log(obj.name); console.log("b = "+b); fn(a);
console.log(obj2.name); console.log(c == d); console.log(a); //2
console.log(obj == obj2); //输出:124 123 true
//输出:猪八戒 猪八戒 false
6.2,变量&函数提升&同名函数
//通过var声明的变量,在定义语句前可访问,值:undefined
var a=3;
function fn () {
console.log(a); //局部有变量a,此时声明未赋值,变量提升
var a=4;
} fn(); //undefined
//通过function声明的函数,在之前可以直接调用
fn2();
function fn2() {
console.log('fn2()');
}
//无函数重载,可以存在同名函数,只要传入的参数数量或者类型不同即可,后覆盖前
function a(){ } var a=3; console.log(typeof a); //function
var c=1; function c(c){ console.log(c); var c=3;} c(2); //报错 原因c不是函数
//先执行函数提升,后变量提升,但变量若赋值,则变量提升先
console.log('gb:'+i);
var i=1;
foo(1);
function foo(i){
if(i==4){
return;
}
console.log('fb:'+i);
foo(i+1);
console.log('fe:'+i);
}
console.log('ge:'+i);
//输出: gb:undefined fb:1 fb:2 fb:3 fe:3 fe:2 fe:1 ge:1
//执行5次上下文,window+foo+内部foo3次
6.3,回调函数
-
定义:自定义,未调用,最终执行了
-
解释:自己作为另外函数的参数,另外函数先执行,自己在执行
-
常见:DOM事件回掉函数/定时器回掉函数/ajax请求回掉函数/生命周期回掉函数
-
IIFE:匿名函数自调用,作用:隐藏实现/不会污染外部模块
document.getElementById('btn').onclick=function(){
alert(this.innerHTML);
} //dom事件回掉函数
setTimeout(function(){
alert('到点了')
},2000) //定时器回掉函数
6.4,作用域与作用域链
-----------------------------------------------------------------------------------------------------------
var x=10; | var obj={ | var name="global"; | var fn=function(){
function fn(){ | fn2:function(){ | if(true){ | console.log(fn);
console.log(x); | console.log(fn2); | var name="local"; | }
} | //console.log(this.fn2); | console.log(name) | fn(); //输出:函数fn
function show(f){ | } | } |
var x=20; | } | console.log(name); |
f(); | obj.fn2(); | //输出:local local |
} | //输出:报错/fn2函数
show(fn); //输出:10 --------作用域链:函数作用域内自上而下引用形成的链式结构 ,即变量没有则从上一级找
6.5,闭包closure
-
变量:函数内部可以直接读取全局变量,函数外部无法读取局部变量,内部声明无var默认全局变量
-
条件:函数嵌套,内部函数引用外部函数的数据(变量/函数)
function f1(){
var n=999; //后面为一个匿名函数,赋值给nAdd,相当于给匿名函数找了个名字
nAdd=function(){n+=1} //nAdd全局变量 本身相当于一个闭包
function f2(){
alert(n); //用处1:可以在函数的外部访问到函数内部的局部变量
}
return f2;
}
var result=f1(); //f1调用后,本应该被垃圾回收机制回收,f2的存在依赖于f1,故f1始终存在
result(); // 999
nAdd(); //用处3:缺点:内存消耗大,会在父函数外部改变父函数内部变量的值
result(); // 1000 //用处2:让这些变量始终保存在内存中,不会随着函数的结束而自动销毁
---------------------------------简洁版---------------------------------------
function fun(){
var count=1;
return function(){
count++;
console.log(count);
}
}
var fun2=fun();
fun2(); //2
fun2(); //3
/***经典面试题****/
for (var i = 1; i <= 5; i++) {
setTimeout( function timer() { //setTimeout(回掉函数,时间)
console.log(i); //时间:执行回掉函数所要延迟的时间
}, 1000 ); //setTimeout()要等执行完函数调用队列中的代码,此时i=6
} //输出:6 6 6 6 6
----闭包方式改进
for (var i = 1; i <= 5; i++) { //把每个定时器所访问的变量独立起来
(function(i){
setTimeout( function timer() {
console.log(i);
}, 1000 );
})(i);
} //输出:1,2,3,4,5
---ES6 新的关键字let
for (let i = 1; i <= 5; i++) { //下同
function fun(n,o){ //var n,o;
console.log(o);
return { //返回一个对象,对象里含函数fun
fun:function(m){ //var m;
return fun(m,n);
}
}
}
var a=fun(0); //undefined
a.fun(1); //0
a.fun(2); //0
a.fun(3); //0
var b=fun(0).fun(1).fun(2).fun(3).fun(30); //undefined 0 1 2 3 30
var c=fun(0).fun(1);
c.fun(2); //1
c.fun(3); //1
function Foo(){
var i=0;
return function(){
document.write(i++);
}
}
var f1=Foo(),
f2=Foo();
f1(); // 0
f1(); // 1
f2(); // 2
6.6,箭头函数
var single = a => a single('a,a'); //'a,a'
var log = () => { alert('no param') } //无参数
var add = (a, b) => a + b //多参数
var add = (a, b) => { //多语句
if (typeof a == 'number' && typeof b == 'number') {
return a + b
} else {
return 0
} //备注:返回对象需用小括号包起来哦
}//不能new 不能使用arguments
6.7,ES6部分
-
var:声明的变量全局有效,可声明多次,有变量提升
-
let :声明的变量只在 let 命令所在的代码块内有效,只能定义一次,无变量提升
-
const :声明一个只读的常量,一旦声明,常量的值就不能改变,故声明必须初始化
const a; //errror
{ let a = 0; var b = 1; } a //undefined b // 1
let a=0; let a=1; var b=0; var b=1; a //error b //1
for (var/let i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i);
})
}// 输出十个 10 0123456789
//let声明的i只在本轮循环中有效,每次循环i都是一个新的变量,所以定时器里面的i其实是不同的变量,JS引擎会记住上一个循环的值
let name = 'outer'
function showName() {
console.log(name)
let name = 'inner'
}
name = 'updatedOuter'
showName() //error 不是updateOuter
-
Symbol :独一无二的值,定义对象的唯一属性名,不能new
let sy = Symbol("KK"); //
let sy1 = Symbol("kk");
sy === sy1; // false
let syObject = {};
syObject[sy] = "kk"; //作对象属性名时用方括号,公有属性,不能出现在循环中
-
扩展运算符:用于操作数组,展开/剩余/解构
let a = [1,2,3];
let b = [0, ...a, 4]; // [0,1,2,3,4]
let obj1 = { a: 1, b: 2 };
let obj2 = { ...obj1, c: 3 }; // { a:1, b:2, c:3 }
let obj3 = { ...obj1, a: 3 }; // { a:3, b:2 }
let a = [1,2,3]; let [b, ...c] = a; b; // 1 c; // [2,3]
let a = [1,2,3]; let [b, ...[c,d,e]] = a; b; // 1 c; // 2 d; // 3 e; // undefined
function test(a, ...rest){ test(1,2,3)
console.log(a); // 1
console.log(rest); // [2,3]
}
let arr1 = ['A', 'B']; let arr2 = ['C']; let arr3 = [...arr1, ...arr2];
console.log(arr3); // ["A", "B", "C"]
day seven
7.1,javascript编程题
//如果数组中存在 item,则返回元素在数组中的位置,否则返回 -1
function indexOf(arr, item) {
if(Array.prototype.indexOf){ //判断浏览器是否支持indexOf方法
return arr.indexOf(item);
}else{
for(var i=0;i<arr.length;i++){
if(arr[i]===item){ //==值相等否 ===值+类型相等否
return i;
}
}
}
return -1;
} //输入:[ 1, 2, 3, 4 ], 3 输出:2
//计算给定数组 arr 中所有元素的总和
function sum(arr) { //eval
return eval(arr.join("+")); //return a;a=eval(...)
}; //forEach
function sum(arr) {
var s = 0;
arr.forEach(function(val, idx, arr) {
s += val;
}, 0);
return s;
};//map的reduce
function sum(arr) {
return arr.reduce(function(prev, curr, idx, arr){
return prev + curr;
});
}
//移除数组 arr 中的所有值与 item 相等的元素。不要直接修改数组 arr,结果返回新的数组
//输入:[1, 2, 3, 4, 2], 2 输出:[1, 3, 4]
function remove(arr,item){ //splice()
var arr1 = arr.slice(0); //复制数组arr
for(var i=0;i<arr1.length;i++){
if(arr1[i] == item){ //是arr1`
arr1.splice(i,1); //是arr1 , arr1=arr1.splice(i,1) 错
i--; //需减哦
}
}
return arr1;
} //push()
function remove(arr,item){
var newarr = [];
for(var i=0;i<arr.length;i++){
if(arr[i] == item)continue;
newarr.push(arr[i]);
}
return nawarr;
}//filter()
function remove(arr,item){
return arr.filter(function(ele){
return ele != item;
})
}
//移除数组 arr 中的所有值与 item 相等的元素,直接在给定的 arr 数组上进行操作,并将结果返回
//输入:[1, 2, 2, 3, 4, 2, 2], 2 输出:[1, 3, 4]
function removeWithoutCopy(arr, item) { //倒序,不用考虑位置影响
for(i=arr.length-1;i>=0;i--)
{
if(arr[i]==item)
{
arr.splice(i,1);
}
}
return arr;
}
//在数组 arr 末尾添加元素 item。不要直接修改数组 arr,结果返回新的数组
var append3 = function(arr, item) {
return arr.concat(item);
};
//找出数组 arr 中重复出现过的元素
//输入:[1, 2, 4, 4, 3, 3, 1, 5, 3] 输出:[1, 3, 4]
function duplicates(arr) { //先排序,在判断
var new_arr = arr.sort();//先把arr排序
var res = [] ;//目标容器
for( var i = 0 ; i < new_arr.length ; i++){
if(new_arr[i] == new_arr[i+1] &&
new_arr[i] !=new_arr[i-1]){//判断是否重复,是否已经放入容器
res.push(new_arr[i]);
}
}
return res;
} //声明数组,以原数组内容为序号
function duplicates(arr) {
var a = [],b = [];
for(var i = 0; i < arr.length; i++){
if(!b[arr[i]]){
b[arr[i]] = 1;
continue;
}
b[arr[i]]++;
}
for(var i = 0; i < b.length; i++){
if(b[i] > 1){
a.push(i);
}
}
return a;
}
//为数组 arr 中的每个元素求二次方。不要直接修改数组 arr,结果返回新的数组
function square(arr) {
var a = [];
arr.forEach(function(e){
a.push(e*e);
});
return a;
}
function square(arr) {
return arr.map(function(e){
return e*e;
})
}
//函数声明,解析器会率先读取并且让其在执行任何代码前可用
//即:别的代码未运行呢,两个getValue声明已经被读取,所以总是执行最新的那个
function functions(flag) { //错误
if (flag) {
function getValue() { return 'a'; } //函数声明
} else {
function getValue() { return 'b'; }
}
return getValue();
} //修改
function functions(flag) {
var getvalue=null; //函数定义
if (flag) {
getValue = function(){ return 'a'; } //函数表达式
} else {
getValue = function() { return 'b'; }
}
return getValue();
}
//修改 js 代码中 parseInt 的调用方式,使之通过全部测试用例
function parse2Int(num) {
return parseInt(num,10); // return parseInt(parseFloat(num));
return val1===val2; //另一题,判断完全等同
if(!num||typeof num!="number") //另一题,num非空,不为数值型
}//例:如果 string 以 "0x" 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数
//输入:function (greeting, name, punctuation) {return greeting + ', ' + name +
// (punctuation || '!');}, ['Hello', 'Ellie', '!'] 输出:Hello, Ellie!
//调用函数有3种方式: obj.func(); func.call(obj,args); func.apply(obj,[m,n......]);
function argsAsArray(fn, arr) {
return fn.apply(this,arr);
}
//转换为er进制,输出第n位,输入:128 8 输出:1
function valueAtBit(num, bit) {
var s = num.toString(2);
return s[s.length - bit];
}
function valueAtBit(num, bit) {
//toString转化为二进制,split将二进制转化为数组,reverse()将数组颠倒顺序
var arr = num.toString(2).split("").reverse();
return arr[bit-1];
}
function valueAtBit(num, bit) {
return (num >> (bit -1)) & 1;
} //return parseInt(str,2); 其它二进制字符串化十进制数
//给定字符串 str,检查其是否包含数字,包含返回 true,否则返回 false
//输入:'abc123' 输出:true
function containsNumber(str) {
var b = /\d/; // return /\d/.test(str)
return b.test(str);
}
function containsNumber(str) {
for(var i=0;i<10;i++){
if(str.indexOf(i)!=-1){
return true;
}
}
return false;
}
function containsNumber(str) {
return !!str.match(/\d/g);
}
function containsNumber(str) {
for(var i=0;i<str.length;i++){
if(Number(str[i])){
return true;
}
}
return false;
}
//给定字符串 str,检查其是否包含连续重复的字母(a-zA-Z),包含返回 true,否则返回 false
function containsRepeatingLetter(str) {
return /([a-zA-Z])\1/.test(str); //要括号,用{2}部分对
} //{2}即有连续两个字母,而\1即有一个同前,前为字母
//函数,返回一个对象,对象的 greeting 属性值等于 str1, name 属性值等于 str2
//对象存在一个 sayIt 方法,该方法返回的字符串为 greeting属性值 + ', ' + name属性值
//原型模式:
function createModule(str1, str2) {
function Obj()
{
this.greeting = str1;
this.name = str2;
}
Obj.prototype.sayIt = function(){return this.greeting + ", " + this.name;} //this不可少
return new Obj();
}//构造函数模式:
function createModule(str1, str2) {
function Obj()
{
this.greeting = str1;
this.name = str2;
this.sayIt = function(){return this.greeting + ", " + this.name;}
}
return new Obj();
}//创建对象模式:
function createModule(str1, str2) {
function CreateObj()
{
obj = new Object;
obj.greeting = str1;
obj.name = str2;
obj.sayIt = function(){return this.greeting + ", " + this.name;}
return obj;
}
return CreateObj();
}//字面量模式:
function createModule(str1, str2) {
var obj =
{
greeting : str1,
name : str2,
sayIt : function(){return this.greeting + ", " + this.name;}
};
return obj;
}
//1、以 $ 开始
//2、整数部分,从个位起,满 3 个数字用 , 分隔
//3、如果为小数,则小数部分长度为 2
function isUSD(str) {
var c=/^\$([1-9]\d{0,2}(,[0-9]{3})*|0)(\.\d{2})?$/;
return c.test(str); //,即,不能“,”.用\.要考虑开头为0的情况,?表示1~2次
}
//给定字符串 str,检查其是否包含 连续3个数字 ,有则返回3个数字,无则返回false
function captureThreeNumbers(str) {
var arr = str.match(/\d{3}/); //注意写法,与test区分
if(arr)
return arr[0];
else return false;
}
//给定字符串 str,检查其是否以元音字母结尾: a,e,i,o,u,以及对应的大写
function endsWithVowel(str) {
// return /(a|e|i|o|u)$/ig.test(str);
return /[aeiou]$/i.test(str);
}
//找出对象 obj 不在原型链上的属性,返回数组,格式为 key: value
function iterate(obj) {
var arr = [];
for(var key in obj){ //for-in循环
if(obj.hasOwnProperty(key)){ //判断是否是对象本身的属性,has..记住,两个大写OP
arr.push(key+": "+obj[key]);
}
}
return arr;
}
//将函数 fn 的[执行上下文]改为 obj,返回 fn 执行后的值
function alterContext(fn, obj) {
return fn.bind(obj)();//.bind()返回的是一个函数,所以需要立即执行。 }
function alterContext(fn, obj) {
return fn.call(obj);
}
function alterContext(fn, obj) {
return fn.apply(obj);
}
//根据两个书中精度较高的一个来确定,先将其转换成字符串,然后根据小数点的位置确定小数位数,
//字符串长度减去‘.'的位置后还要再减去1得到正确的小数位数,两个取其大,然后用toFixed()函数确定
function multiply(a, b) { //小数相乘,注意精度问题
//求两个数中精度大的一个
var stra=a.toString(); //toString(2) 转换成2进制字符
var strb=b.toString(); //好像search函数没人用耶
var len=Math.max(stra.length-stra.indexOf('.')-1,strb.length-strb.indexOf('.')-1);
return parseFloat(a*b).toFixed(len); //其它如字符串parseInt转换成10进制数
}
//将给定数字转换成二进制字符串。如果字符串长度不足 8 位,则在前面补 0 到满8位
function convertToBinary(num) {
return ('00000000' + num.toString(2)).slice(-8);
}
function convertToBinary(num) {
var str = num.toString(2);
while(str.length < 8) {
str = "0" + str;
}
return str;
}
//在JavaScript中,函数是一种对象,其上下文是可以变化的,对应的,函数内的this也是可以变化的。
//函数可以作为一个对象的方法,也可以同时作为另一个对象的方法
//可以通过Function对象中的call或者apply方法来修改函数的上下文
function speak(fn, obj) { //将函数 fn 的执行上下文改为 obj 对象
return fn.apply(obj,obj);
}
//输入:functionFunction('Hello')('world') 输出:Hello, world
function functionFunction(str) {
var f = function(s){
return str+", "+s;
}
return f;
}
//1、返回一个函数数组 result,长度与 arr 相同
//2、运行 result 中第 i 个函数,即 result[i](),结果与 fn(arr[i]) 相同
function makeClosures(arr, fn) { //闭包
var result=[];
for(let i=0;i<arr.length;i++){
result[i] = function(){
return fn(arr[i]); //let声明的变量只在let所在代码块内有效
};
}
return result;
}
//已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件:
//1、返回一个函数 result,该函数接受一个参数
//2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致
//call和apply必须显式地调用str3,立即执行this用于上下文不确定,bind不是立即执行,未传参知返回函数
function partial(fn, str1, str2) {
function result(str3) {
return fn.call(this, str1, str2, str3);
}
return result;
} // apply
function partial(fn, str1, str2) {
function result(str3) {
return fn.apply(this, [str1, str2, str3]);
}
return result;
}// bind生成新函数(对象), 它的str1, str2参数都定死了, str3未传入, 一旦传入就会执行
function partial(fn, str1, str2) {
return fn.bind(this, str1, str2); // 或 return fn.bind(null, str1, str2);
}// 匿名函数,默认this绑定global,与bind的第一个参数为this时效果一样
function partial(fn, str1, str2) {
return function(str3) {
return fn(str1, str2, str3);
}
}// ES6。this指向undefined.
const partial = (fn, str1, str2) => str3 => fn(str1, str2, str3);
//函数 useArguments 可以接收 1 个及以上的参数
//实现函数 useArguments,返回所有调用参数相加后的结果 测试参数全部为 Number 类型
function useArguments() { //是slice同时无()
var arr=Array.prototype.slice.call(arguments)//把arguments类数组转化为数组,有s并非真数组
return eval(arr.join("+"));//求和 eval别平措了
}
function useArguments() {
var sum = 0; //arguments能获得函数对象传入的参数组,类似与一个数组,能够通过length获取参数个数
for(var i = 0; i < arguments.length; i++){
sum += arguments[i];
}
return sum;
}
//实现函数 callIt,调用之后满足如下条件
//1、返回的结果为调用 fn 之后的结果
//2、fn 的调用参数为 callIt 的第一个参数之后的全部参数
function callIt(fn) {
//将arguments转化为数组后,截取第一个元素之后的所有元素
var args = Array.prototype.slice.call(arguments,1);
//调用fn
var result = fn.apply(null,args);
return result;
}
//实现函数 partialUsingArguments,调用之后满足如下条件:
//1、返回一个函数 result
//2、调用 result 之后,返回的结果与调用函数 fn 的结果一致
//3、fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数
function partialUsingArguments(fn) {
var a=Array.prototype.slice.call(arguments,1);
var result=function(){
var b=Array.prototype.slice.call(arguments);
return fn.apply(this,a.concat(b)); //this apply()因为对象和参数都变了
}
return result;
}
//实现一个打点计时器,要求
//1、从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 1
//2、返回的对象中需要包含一个 cancel 方法,用于停止定时操作
//3、第一个数需要立即输出
function count(start, end) {
console.log(start++);//立即输出第一个值
var timer = setInterval(function(){
if(start <= end){
console.log(start++);
}else{
clearInterval(timer);
}
},100);
return {//返回一个对象
cancel : function(){
clearInterval(timer);
}
};
}
//封装函数 f,使 f 的 this 指向指定的对象
function bindThis(func, oTarget) {
return function(){
return func.apply(oTarget, arguments);
};
}
function bindThis(f, oTarget) {
return f.bind(oTarget);
}
//删除数组 arr 最后一个元素。不要直接修改数组 arr,结果返回新的数组
function truncate(arr) {
return arr.slice(0,-1);
}//利用filter
function truncate(arr) {
return arr.filter(function(v,i,ar) {
return i!==ar.length-1;
});
}//利用push.apply+pop
function truncate(arr) {
var newArr=[];
[].push.apply(newArr, arr);
newArr.pop();
return newArr;
}//利用join+split+pop 注意!!!:数据类型会变成字符型
function truncate(arr) {
var newArr = arr.join().split(',');
newArr.pop();
return newArr;
}//利用concat+pop
function truncate(arr) {
var newArr = arr.concat();
newArr.pop();
return newArr;
}//普通的迭代拷贝
function truncate(arr, item) {
var newArr=[];
for(var i=0;i<arr.length-1;i++){
newArr.push(arr[i]);
}
return newArr;
}
PS:小技巧,同一改名,alt+shift+r
开启计时器 console.time("计时器的名字") 字符串作为参数
终止计时器 console.timeEnd("test"); //网页打开--》检查---》console即可看到
通过Math.sqrt()对一个数进行开方 j<=Math.sqrt(i)
mianji() - 调用函数 - 相当于使用的函数的返回值 mianji 函数对象
Hbuilder编辑技巧:
h+8 :创建基本页面
div#page>div.logo+ul#navigation>li*2>a
Sublime text:
https://blog.csdn.net/weixin_40682842/article/details/78727266