<textarea style="" name="test-editormd-markdown-doc"># 变量声明 #
讯享网
变量的命名规则
- 变量名必须以英文字母、_、$开头
- 变量名可以包括英文字母、_、数字
- 不可以用系统的关键字、保留字作为变量名
值类型
js中的值类型也就是数据类型,分为不可改变的原始值(栈数据)和引用值(堆数据)
原始值
number string boolean undefined null
引用值
array object function date regexp
区别
原始值是存放到栈里面,栈的特点是先入后出。
引用值是存放在堆里面,堆里面存放的是内容,栈里面存放的是堆的地址。
斐波那契数列
讯享网var n = parseInt(window.prompt('input')); var first =1,second=1,third; if(n>2){ for(var i=0;i<n-2;i++){ third=first+second; first=second; second=third; } document.write(third); }else{ document.write(1); }
求100以内的所有的质数
var count=0; for(var i=1;i<100;i++){ for(var j=1;j<=i;j++){ if(i%j==0){ count++; } if(count==2){ document.write(i+" "); } count=0; } }
break与continue
编程的两种形式
面向过程和面向对象
函数声明的三种方式
讯享网function 函数名(){ } var 变量=function 函数名(){ } //命名函数表达式 var 变量=function(){ } //此函数为匿名函数表达式
函数形参与实参
形参的个数可以超过实参
没有赋值的形参是undefined
形参的个数可以小于实参
形参都放在arguments中
形参的个数:arguments.length
实参的个数:函数名.length
但是当个数不相同的时候,特别是实参个数少于形参的时候,则不会改变没有形参参数的数值
获取字符串的每一位的两种方式
str[0] str.charAt(0)
字符串反转:123转为仨俩壹
function reverse(){ var num = window.promt('input'); var str=""; for(var i=num.length-1;i>=0;i--){ str+=transer(num[i]); } document.write(str); } function transfer(target){ switch(target){ case "1": return '壹'; case "2": return '俩'; case "3": return "仨"; } }
利用递归写阶乘函数
讯享网function jc(n){ if(n == 1){ return 1; } return n*jc(n-1); }
使用递归需要注意两点:
- 找规律;
- 找出口;
利用递归写斐波那契数列
function fb(n){ if(n==1||n==2){ return 1; } return fb(n-1)+fb(n-2); }
js运行三部曲
- 语法分析
- 预编译
- 解释执行
预编译
函数声明整体提升,变量 声明提升
imply global 暗示全局变量: 即任何变量,如果变量未经声明就赋值,此变量就为全局对象所有。
一切声明的全局变量,都是window的属性 。
预编译的四部曲:
- 创建AO对象
- 找形参和变量声明,将变量和形参名作为AO属性名,值为Undefined
- 将实参值和形参相统一
- 在函数体里面找函数声明,值赋予函数体
任何执行期上下文中的this都指向的是window,通过New关键字的方式,可以进行构造函数创建对象,改变this指向,this最终指向的是创建的对象。
for循环中出现闭包的情况
如果在for循环中,对每一个元素都绑定一个函数的话,则会形成闭包
讯享网function test(){ var arr = []; for(var i=0;i<10;i++){ arr[i]=function(){ console.log(i); } } return arr; }
解决for循环中的闭包问题的方法就是使用立即执行函数
function test(){ var arr=[]; for(var i=0;i<10;i++){ (function(j){ arr[j]=function(){ console.log(j); } })(i) } }
几道大厂前端笔试题




2015年阿里笔试题
讯享网function test(){ var liCollection = document.getElementsByTagName('li'); for(var i=0;i<liCollection.length;i++){ (function(j){ liCollection[j].onclick=function(){ console.log(j); } }(i)) } }
利用立即执行函数解决for循环中的闭包问题
写一个方法,求一个字符串的字节长度

function retByteslen(target){ var count = target.length; for(var i=0;i<target.length;i++){ if(target.charCodeAt(i)>255){ count ++; } } }
解题思路: 汉字的字符比英文的字符多1个;
提取变量后可以如下编写函数:

构造函数的内部原理
- 在函数体最前面隐式的加上this={}
- 执行 this.xxx=xxx;
- 隐式的返回this
原型
- 定义:原型是function 对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
- 利用原型的特点和概念,可以提取共有属性。
- 对象如何查看原型,可以通过 proto
- 对象如何查看对象的构造函数 constructor
- 构造函数有个自带的属性叫prototype,也就是原型,是一个对象。
构造函数的最终级别的原型就是 Object.prototype
绝大多数的对象最终都会继承自Object.prototype,也有可能是Null;

创建对象的方式可以是:Object.create(原型);
创建对象的两种方式
讯享网var obj={ };//通过对象字面量的方式进行创建 var obj1=new Object();
js有精度问题,所以一般都不处理数据
call/apply
作用:改变this指向
区别:后面传的参数形式不同
第一个参数都是改变后的this,如果传的是null,则不改变this指向
call后面的参数是一个个进行传递的,apply后面的参数是一个arguments数组
继承的问题
function inherit(Target,Origin){ function F(){ }; F.prototype=Father.prototype; Son.prototype=new F(); } Father.prototype.lastName="Deng"; function Father(){ }; function Son(){ };
通过中间变量的形式可以解决共用原型链的问题
通过中间变量解决共用原型链的模式叫:“圣杯模式”;
圣杯模式(解决共用原型的问题)
讯享网function inherit(Target,Origin){ function F(){ }; F.prototype=Origin.prototype; Target.prototype=new F(); Target.prototype.constructor=Target; Target.prototype.uber=Origin.prototype; } Father.prototype.lastName='Deng'; function Father(){ } function Son(){ } inherit(Son,Father); var son = new Son(); var father = new Father();
命名空间
原生javascript实现仿jquery链式调用
var deng = { smoke:function(){ console.log('smoking'); return this; }, dirnk:function(){ console.log('dirnking'); return this; }, perm:function(){ console.log('preming'); return this; } } deng.smoke().dirnk();
通过return this的方式,可以保证每个函数都可以返回自身对象,所以都可以链式调用的。
对象的枚举
for in
hasOwnProperty这个是对象原型链上的判断属性是不是它自己的一个方法
in 判断这个属性名是不是当前对象的,如果是对象原型上面的,也会返回true的
instanceof A instanceof BA对象是不是B构造函数构造出来的 等同于 A对象的原型链上有没有B的原型
判断对象和数组的三种方法
可以通过Instanceof进行数组和对象的判断
[] instanceof Array 结果是true;
{} instanceof Array 结果是false;
可以通过constructor进行数组和对象的判断
[].contructor结果是Array;
{}.constructor的结果是Object;
可以通过toString()方法进行数组和对象的判断
Object.prototype.toString.call([]) 结果是 “[object Array]”;
Object.prototype.toString.call({}) 结果是“[object Object]”;
Object.prototype.toString.call(123) 结果是"[object Number]"
this
- 函数预编译过程中 this指向的是window
- 全局作用域里 this指向的是window
- call/apply可以改变函数运行时的this指向
- obj.func() func()里面的this指向obj
callee与caller
立即执行函数,执行完成后,函数会销毁,所以此时可以通过arguments.callee的方式进行调用递归函数
讯享网var num = (function (n){ if(n==1){ return 1; } return n * 阶乘(n-1);//此时的阶乘可以用 arguments.callee(n-1);来代替 }(100)) function test(){ demo(); } function demo(){ console.log(demo.caller); } test();
深度克隆
function deepClone(origin,target){ var target = target || { }, toStr = object.prototype.toString, arrStr="[object Array]"; for(var prop in origin){ if(origin[prop] !== "null" && typeof(origin[prop])=="object"){ target[prop]=toStr.call(origin[prop])==arrStr?[]:{ }; deepClone(origin[prop],target[prop]); }else{ target[prop]=origin[prop]; } } return target; }
自己写一个push方法
讯享网var arr = [1,2,3]; Array.prototype.push=function(){ for(var i =0;i<arguments.lengthd;i++){ this[this.length]=arguments[i]; } return this.length; }
数组的几个方法
push是可以在数组的最后一位进行添加,可以添加多个参数。
pop是可以把数组的最后一位剪切出去,传递参数也是没有用的,只会截取最后一位。
unshift是在数组的前面进行添加,可以传递参数,也可以传递多个参数。
shift是在数组的前面进行删除,传递参数也是没有用的。
slice是数组的截取方法,是从第一个参数位开始截取,截取到第二个参数位为止。如果只有一个参数的话,则截取到数组的最后一位。
sort是进行数组的排序,最终会改变原数组。此处的排序不会完全按照数字大小进行排序,是ASCII码。
splice是截取,有三部分参数,第一个参数是从第几位开始,第二个参数是截取多少的长度,第三个以及后面的参数是在数组切口处添加的新的数据。
自己写一个splice方法
splice = function (pos){ pos += pos>0?0:this.length; }
自己写一个sort方法
讯享网arr.sort(function(a,b){ return b-a;//降序排列 return a-b;//升序排列 })
给一个有序数组乱序
arr.sort(function(a,b){ return Math.random()-0.5; })
按照字符串的长度进行排序
讯享网var arr = ['ad','ddd','ddddd'] arr.sort(function(a,b){ return a.length-b.length;//升序 }); for(var i=0;i<arr.length;i++){ for(var j=0;j<i;j++){ arr.sort(function(i,j){ return i.length - j.length; }) } }
按照字符串的字节长度进行排序
function retBytes(str){ var num = str.length; for(var i=0;i<str.length;i++){ if(str.charCodeAt(i) > 255){ num ++; } return num; } } var arr =['asdf','ddd','adgdasg']; arr.sort(function(a,b){ return retBytes(a) - retBytes(b); })
包装type函数
讯享网function type(target){ var template = { "[object Array]":"array", "[object Object]":'object', "[object Number]":'numer - object', "[object Boolean]":'boolean - object', "[object String]":'string - object' } if(target === null){ return "null"; } if(typeof (target) == "object"){ var str = Object.prototype.toString.call(target); return template[str]; }else{ return typeof(target); }else{ return ret; } }
在数组原型上面添加一个数组去重的方法
Array.prototype.unique=function(){ var temp={ }, arr=[], len=this.length; for(var i=0;i<len;i++){ if(!temp[this[i]]){ temp[this[i]] = "abc"; arr.push(this[i]); } } return arr; }
str.split("")
字符串打散成数组
事件委托
讯享网var ul = document.getElementsByTagName('ul')[0]; ul.onmouseover = function (e){ var event = e|| window.event; var target = event.target || event.srcElement; target.style.backgroundColor="rgba(0,255,)"+target.getAttribute('img-date')+")"; target.setAttribute('img-date',parseInt(target.getAttribute('img-date'))+6); }
元素的鼠标滑过事件,event target这两个参数兼容性的处理,e.target元素获取属性的方式是:
target.getAttribute('css属性'),设置元素的属性:target.setAttribute('css属性',parsetInt(target.getAttribute('css属性')));
创建一个div并添加到body中(原生Js)
var newDiv = document.createElement('div'); document.body.appendChild(newDiv);
封装一个获取元素子节点的方法
讯享网var div = document.getElementsByTagName('div')[0]; function retElementChild(node){ var temp = { length:0, push:Array.prototype.push, splice:Array.prototype.splice }, child = node.childNodes, len = child.length; for(var i=0;i<len;i++){ if(child[i].nodeType === 1){ temp.push(child[i]); } } return temp; }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/182893.html