写在前面:debugger 代码可以帮助调试,或者手动在js里打断点
1.
var a = [];
for (var i = 0; i < 10; i++) {
a[i] = function () {
console.log(i);
};
}
a[6](); // 10
我觉得i是在这个for循环的作用域里的,然后i使用过的时候是9,最后++变成了10,所以输出的i是10
......................................ctrl++可以放大谷歌控制台字体.....................
2.i++ 和++i的区别,前者是先使用再赋值,后者是先赋值再使用
(1)var i=1;
console.log(i); // 输出1
var a=i++;
console.log(i); //输出2
console.log(a); //输出1
(2)
var i=1;
console.log(i);
var a=++i;
console.log(i); //输出2
console.log(a); //输出2
3.使用let
命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”
“暂时性死区”也意味着typeof
不再是一个百分之百安全的操作。
总之,暂时性死区的本质就是,只要一进入当前作用域,所要使用的变量就已经存在了,但是不可获取,只有等到声明变量的那一行代码出现,才可以获取和使用该变量。
2018/01/29
4. 变量提升 只有var会有的问题,let不会
JavaScript 中,函数及变量的声明都将被提升到函数的最顶部。
JavaScript 中,变量可以在使用后声明,也就是变量可以先使用再声明 i=7 console.log(i) var i
JavaScript 只有声明的变量会提升,初始化的不会console.log(i) var i=7;
5. http://blog.csdn.net/qq673318522/article/details/50810650 函数作用域和声明提前
var scope = 'global';
function f(){
console.log(scope);
var scope = 'local';
console.log(scope);
}
由于函数内声明提升,所以上面的代码实际上是这样的
var scope = 'global';
function f(){
var scope; //变量声明提升到函数顶部
console.log(scope);
scope = 'local'; //变量初始化依然保留在原来的位置
console.log(scope);
}
由于scope在第一个console.log(scope)语句之前就已经定义了,但是并没有赋值,因此此时scope的指是undefined.
第二个console.log(scope)语句之前,scope已经完成赋值为’local’,所以输出的结果是local。
var getName = function(){
console.log(2);
}
function getName (){
console.log(1);
}
getName();
可能会有人觉得最后输出的结果是1。让我们来分析一下,这个例子涉及到了变量声明提升和函数声明提升。正如前面说到的函数声明提升,函数声明function getName(){}的声明会被提前到顶部。
而函数表达式var getName = function(){}则表现出变量声明提升。因此在这种情况下,getName也是一个变量,因此这个变量的声明也将提升到底部,而变量的赋值依然保留在原来的位置。因此上面的函数可以转换成下面的样子:
var getName; //变量声明提升
function getName(){ //函数声明提升到顶部
console.log(1);
}
getName = function(){ //变量赋值依然保留在原来的位置
console.log(2);
}
getName(); // 最终输出:2
6.css 实现img模糊
filter: url(blur.svg#blur); /* FireFox, Chrome, Opera */
-webkit-filter: blur(10px); /* Chrome, Opera */
-moz-filter: blur(10px);
-ms-filter: blur(10px);
filter: blur(10px);
filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius=10, MakeShadow=false); /* IE6~IE9 */
2018.11.29
7.
可以使用localeCompare() 方法来实现中文按照拼音排序,方法相当简单
var array = ['白鸽', '麻雀', '大象', '狗', '猫', "鸡"];
array = array.sort(function compareFunction(item1, item2) {
return item1.localeCompare(item2);
});
//["白鸽", "大象", "狗", "鸡", "麻雀", "猫"]
8.
而且可以通过如下代码实现中文按照拼音排序,并且可以将中文按照a,b,c,d……进行区分。代码如下:
function pySegSort(arr,empty) {
if(!String.prototype.localeCompare)
return null;
var letters = "*abcdefghjklmnopqrstwxyz".split('');
var zh = "阿八嚓哒妸发旮哈讥咔垃痳拏噢妑七呥扨它穵夕丫帀".split('');
var segs = [];
var curr;
$.each(letters, function(i){
curr = {letter: this, data:[]};
$.each(arr, function() {
if((!zh[i-1] || zh[i-1].localeCompare(this) <= 0) && this.localeCompare(zh[i]) == -1) {
curr.data.push(this);
}
});
if(empty || curr.data.length) {
segs.push(curr);
curr.data.sort(function(a,b){
return a.localeCompare(b);
});
}
});
return segs;
}
console.log(JSON.stringify(pySegSort(['白鸽', '麻雀','黑','大象', '狗', '猫','妈妈','马', "鸡",'瘦','胖'])));
9.
实现字母、数字的混合排序:
var d = [1,2,3,'a','k','b','d',10,20,'c']
d.sort(function(a,b){
var c = isFinite(a), // 如果 number 是有限数字(或可转换为有限数字),那么返回 true。否则,如果 number 是 NaN(非数字),或者是正、负无穷大的数,则返回 false。
d = isFinite(b);
return (c != d && d - c) || a > b;
})
console.log(d);
//[1, 2, 3, 10, 20, "a", "b", "c", "d", "k"]
isFinite() 判断a、b是否是数字。
return 后面的语句:
c != d && c - d 如果c和d不相等 ,也就是说比较的值不是同一类型。那就比较 c-d的值是1还是-1(中间进行了隐式类型转换)
如果c == d 也就是说c、d是同一类型的值,c、d可能都是字母,也可能都是数字。这里就可以直接比较大小了(都是字母的话不能直接做减法)。
isFinite() 函数用于检查其参数是否是无穷大。如果 number 是有限数字(或可转换为有限数字),那么返回 true。否则,如果 number 是 NaN(非数字),或者是正、负无穷大的数,则返回 false。
10.js里的小数计算,由于小数在计算时会先转换为二进制,存在精度丢失,所以小数计算的结果不是非常准确
11. + 比较偏向字符串,连接的操作数其中一个是字符串的话,则都转换为字符串,比较运算符,> < 更偏爱数字,只有当两个操作数都是字符串的时候才会进行字符串的比较。
12.
// in 运算符作用:
// 就是判断 属性是否存在于对象中,如果存在,返回值为:true
// 如果不存在,则为:false
// 语法:属性 in 对象
// var obj = {
// name1: "jack",
// age: 9,
// abc: undefined
// };
// 如果是name,要注意:window有name属性
// console.log("name1" in obj); // true
// console.log("age" in obj);
// console.log("age123" in obj);
// 如果是对象中存在的成员或者是原型中的成员,此时,返回的结果就是 true
// console.log("toString" in obj);
// console.log(obj.toString());
// console.log("abc" in obj);
// in运算符判断数组
// 对于数组来说,索引号 就是属性
var arr = [1];
// console.log("1" in arr); // false
// console.log("0" in arr); // true
// console.log(0 in arr); // true
13. p && p.x 与,短路行为,只有当左侧的是真的时候才会运行右侧的,如果p为null,则直接返回null ,不去计算右侧,所以不会报错,
14.!非,具有很高的优先级,想要对表达式进行非的话,要用(), !(a==b)
15.typeof(null) 返回的是object
16.----.map(Number);可以将一个逗号隔开的数字字符串转换为数组
var str="11,5,4"
var a=str.split(",").map(Number);
console.log(a)
17. a[-12]=12;
a[1.25]=12;
可以使用负数或者非整数索引数组,但是会把数字转化为字符串,同时赋予这个数组一个“-12”属性
18.函数的实参,arguments对象,function a(x,y,z){
arguments.length //3
arguments[0] //x
}
19.闭包 跟垃圾回收机制有关
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
闭包的两个作用,一个是前可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中,不会在外部函数调用后被自动清除。
局部变量被保存下来是因为,返回了一个内部函数,内部函数引用了这个局部变量,所以不会被释放回收,
使用闭包的注意点
(1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
(2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
珠峰培训里看的:
函数执行的一瞬间叫闭包,闭包就是产生一个不销毁的作用域,当执行后返回的结果是引用数据类型,被外界接收,此时不会销
毁,内部声明的变量都是私有的,所以可以模块化,
20.reduce 求和 a=[{price:12,num:2},{price:5,num:3}]
a.reduce((prev,next)=>{return prev+next.price*next.num},0)
21.图片预览
简单的来说就是,就是替换img的src;而读取URL有filereader 和 URL.createObjectURL 两种预览方式。这两种方式可以获得上传图片的名字(name)
filereader 的方法:
//filereader 的方法
<form action="" enctype="multipart/form-data">
<input id="file" class="filepath" οnchange="changepic(this)" type="file"><br>
<img src="" id="show" width="200">
</form>
<script>
function changepic() {
var reads= new FileReader();
f=document.getElementById('file').files[0];
reads.readAsDataURL(f);
reads.οnlοad=function (e) {
document.getElementById('show').src=this.result;
};
}
</script>
createObjectURL的方法:
//createObjectURL的方法
<form action="" enctype="multipart/form-data">
<input id="file" class="filepath" οnchange="changepic(this)" type="file"><br>
<img src="" id="show" width="200">
</form>
<script>
function changepic(obj) {
//console.log(obj.files[0]);//这里可以获取上传文件的name
var newsrc=getObjectURL(obj.files[0]);
document.getElementById('show').src=newsrc;
}
//建立一個可存取到該file的url
function getObjectURL(file) {
var url = null ;
// 下面函数执行的效果是一样的,只是需要针对不同的浏览器执行不同的 js 函数而已
if (window.createObjectURL!=undefined) { // basic
url = window.createObjectURL(file) ;
} else if (window.URL!=undefined) { // mozilla(firefox)
url = window.URL.createObjectURL(file) ;
} else if (window.webkitURL!=undefined) { // webkit or chrome
url = window.webkitURL.createObjectURL(file) ;
}
return url ;
}
</script>
以上是两种方法,按照前辈们的说法,creatObjectURL可以有更好的性能,或许是浏览器自带接口的原因, 可以处理的更快。
22.正则介绍 https://www.cnblogs.com/chenmeng0818/p/6370819.html
代表特殊含义的元字符
\d : 0-9之间的任意一个数字 \d只占一个位置
\w : 数字,字母 ,下划线 0-9 a-z A-Z _
\s : 空格或者空白等
\D : 除了\d
\W : 除了\w
\S : 除了\s
. : 除了\n之外的任意一个字符
\ : 转义字符
| : 或者
() : 分组
\n : 匹配换行符
\b : 匹配边界 字符串的开头和结尾 空格的两边都是边界 => 不占用字符串位数
^ : 限定开始位置 => 本身不占位置
$ : 限定结束位置 => 本身不占位置
[a-z] : 任意字母 []中的表示任意一个都可以
[^a-z] : 非字母 []中^代表除了
[abc] : abc三个字母中的任何一个 [^abc]除了这三个字母中的任何一个字符
代表次数的量词元字符
* : 0到多个
+ : 1到多个
? : 0次或1次 可有可无
{n} : 正好n次;
{n,} : n到多次
{n,m} : n次到m次
23.对象直接等于另一个对象是浅拷贝,一个里边的属性改变,另一个里的也会改变,但是如果一个等于null或者“”,另一个不变,而且等于null的
let user={name:"aa"};
console.log(user) //{name: "aa"}
let aaa=user;
console.log(aaa);//{name: "aa"}
user.name='123';
console.log(user);//{name: "123"}
console.log(aaa);//{name: "123"}
aaa.name="789"
console.log(user);//{name: "789"}
console.log(aaa);//{name: "789"}
但是如果一个等于null或者“”,另一个不变,
// user=null;
// console.log(user);//null
// console.log(aaa);//{name: "789"}
user=''
console.log(user);//''
console.log(aaa);//{name: "789"}
24.如果要将一个已经声明的变量用于解构赋值,必须非常小心。
// 错误的写法
let x;
{x} = {x: 1};
// SyntaxError: syntax error
25.“”==0 true null==0 false “0”==0 true 0==0 true 0===0 true “0”===0 false
let ddd=0; 不弹出
if(ddd){
alert(333)
}
26.js的精确的四舍五入和乘法
//乘法和四舍五入分开
/**
* @param {Number} arg1 要相乘的数
* @param {Number} arg2 要相乘的数
* @returns {Number} 相乘的结果
*/
function accMul(arg1,arg2) {//精确的乘法,含浮点数(小数)的乘法结果不准确
var m=0,s1=arg1.toString(),s2=arg2.toString();
try{m+=s1.split(".")[1].length}catch(e){}
try{m+=s2.split(".")[1].length}catch(e){}
return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
}
/**
* @param {Number} num 要四舍五入的值
* @param {Number} point 保留几位小数
* @returns {Number} 保留point位小数四舍五入后的数值
*/
function myToFixed(num,point){//精确的四舍五入
if(isNaN(num)){
return null;
}
point=Math.pow(10,point);
num= Math.round(accMul(num,point))/point
return num
}
27.jquery用attr('checked','checked')不起作用,要用prop()方法
$(“input[type=’radio’] [value=’0’]”).prop(“checked”,true);
28. new Date('2014-1-1')ios不认,所以要改成 new Date('2014/1/1') 就可以了
29.禁止浏览器拖拽文字
<table ondragstart="return false;">
30.for 和 forEach 的return false
for(let i=0;i<this.payList.length;i++){
if(!this.payList[i].payName){
return false;//不会继续执行底下
}
}
this.payList.forEach(item=>{
if(!item.payName){
return false;//会继续执行底下
}
})
31.js中,判断 aa.bb==2 对象中的子属性的时候,一定要判断该对象存在再判断子属性, aa&&aa.bb==2,不然aa='',就会报错