JavaScript模拟题

文章目录

1.JavaScript中如何检测一个变量是String类型

function checkString(arg){
	return typeof(arg) == "string";
}
checkString('abc');

2.如何检测变量是一个数组

var arr = [];
isArray(arr);
function isArray(arg){
	return Object.prototype.toString.call(arg) === '[object Array]'
}

3.用js去除字符串空格

a. replace正则匹配

str = str.replace(/\s*/g.""); //去除所有空格
str = str.replace(/^\s*|\s*$/g,"");  //去除两头空格
str = str.replace(/^\s*/,"")//去除左空格
str = str.replace(/(\s*$)/g,"")//去除右空格

b. str.strim()方法,strim()无法去除中间空格

var str = " xiao wen";
var str2 = str.trim();
alert(str2);

c.jquery,$.trim(str)

var str = " xiao wen";
var str2 = $.trim(str);
alert(str2);

4…获取浏览器URL中查询字符串中的参数

//假设测试地址为:测试地址为:http://www.runoob.com/jquery/misc-trim.html?channelid=12333&name=xiaoming&age=23

function getWindowHref(){
	var gHref = window.location.href;
	var args = gHref.split('?');
	if(args[0] == gHref){
		return "";
	}
	var obj = {};
	var arr = args[1].split('&');
	for (var i=0;i<arr.length;i++){
		var arg = arr[i].split("=");
		obj[arg[0]] = arg[1];
	}
	return obj;
}
var href = getWindowHref();
alert(href['name']);

5.js操作字符串

添加、移除、移动、复制、创建和查找节点

5.1创建新节点

createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点

5.2添加、移除、替换、插入

appendChild() //添加
removeChild() //移除
replaceChild() //替换
insertBefore() //插入

5.3查找

getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性

6写出3个使用this的典型应用

6.1在html元素属性中

<input type="button" onclick="showInfo(this);" value="点击一下" />

6.2构造函数

function Animal(name, color){
	this.name = name;
	this.color = color;
}

6.3input点击,获取值

<input type="button" id="text" value="点击一下" />
var btn = document.getElementById("text");
btn.click = function(){
	alert(this.value);
}

7.apply()与call()求数组最值

var numbers = [5, 15, 25, -35];
var maxNumber = Math.max.apply(this, numbers);
alert(maxNumber);
var maxNumber2 = Math.max.call(this, 5, 15, 25, -35);
alert(maxNumber2);

8.typeof与instanceof的区别

  • 相同点:都常用来判断一个变量是否为空,或类型。
  • typeof
    • 返回一个字符串,用来说明变量的数据类型返回一个字符串,用来说明变量的数据类型:number,string,boolean,object,function,undefined
    • typeof来获取一个变量是否存在,如if(typeof a!=“undefined”)…,而不要使用if(a),因为当a不存在(未声明)时会出错
      typeof对于array,null,一律返回object
  • instanceof,用于判断一个变量是否是对象实例
var a = new Array();
a instanceof Array?alert("true"):alert("false"); //a是数组的实例?真:假
a instanceof Object?alert("true"):alert("false"); //a是对象的实例?真:假

function test(){};
var a = new test();
alert(a instanceof test);

if(window instanceof Object){
	alert("Yes");
}
else{
	alert("False");
}

9.闭包

定义用法:当一个函数的返回值是另外一个函数,而返回的那个函数如果调用了其父函数内部的其他变量,如果返回的这个函数在外部被执行,就产生了闭包。
表现形式:使函数外部能够调用函数内部定义的变量

  1. 根据作用域链的规则,底层作用域没有声明的变量,会向上一级找,找到就返回,没找到就一直找,知道window的变量,没有就返回undefined。
var count = 10; //全局作用域
function add(){
  var count = 0;     //函数全局作用域
  return function(){
  	count +=1;   //函数的内部作用域
  	alert(count);
  }
}
var s = add();
s();   //1
s();   //2

2. 变量的作用域
作用域分全局变量和局部变量

  • 函数内部可以读取函数外部的全局变量;函数外部无法读取函数内的局部变量
  • 函数内部声明变量的时候,一定要使用var命令,如果不用的话,会变成一个全局变量的声明
    3. 闭包的注意事项
  • 滥用会造成内存泄露,因为闭包使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。因此,解决方法是在退出函数之前,将不使用的局部变量全部删除
  • 会改变父函数内部的值。所以,如果把父函数当做对象使用,把闭包当做它的公共方法,把内部变量当做它的私有属性。这是,不要随便改变父函数内部变量的值

10.跨域,跨域请求资源的方法

  1. 跨域
    由于浏览器同源策略,凡是发送请求ur的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。情况如下:由于浏览器同源策略,凡是发送请求ur的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。情况如下:
    • 网络协议不同,如http协议访问https协议
    • 端口不同,如80端口访问8080端口
    • 域名不同,xxx.com访问bb.com
    • 子域名不同,aa.xxx.com访问bb.xxx.com
    • 域名和域名对应ip,如www.a.com访问20.205.28.90

2.** 方法**
a. proxy代理
定义和用法,proxy代理用于将请求发送给后台服务器,通过服务器来发送请求,然后将请求的结果传递给前端。
实现方法:通过nginx代理
注意点:
1.如果是https协议的请求,那么你的proxy首先需要信任该整数(尤其是自定义证书)或者忽略证书检查,否则你的请求无法成功。

b. cors(cross-origin resource sharing),
定义和用法,是现代浏览器支持跨域资源请求的一种最常见的方式
使用方法:一般需要后端人员在处理请求数据的时候,添加允许跨域的相关操作,如下:

res.writeHead(200, {
	"Content-Type": "text/html; charset=UTF-8",
	"Access-Control-Allow-Origin": 'http://localhost',
	"Access-Control-Allow-Methods": 'GET, POST, OPTIONS',
	"Access-Control-Allow-Headers": 'X-Requested-With, Content-Type'
})

c. jsonp
定义和用法,通过动态插入一个scrip标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会立即执行(在没有阻塞的情况下)。
特点:通过情况下,通过动态创建script来读取他域的动态资源,获取的数据一般为json格式。

var _script = document.createElement('script');
_script.type = "text/javascript";
_script.src = "http://localhost:8888/jsonp?callback=testjsonp";
document.head.appendChild(_script);

function testjsonp(data){
	console.log(data.name);            //获得返回结果
}

缺点:

  • 这种方式无法发送post请求;
  • 另外要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定

11.垃圾回收

定义:垃圾回收(Garbage Collection),执行环境负责管理代码执行过程中使用的内存。
原理:GC会定期(周期性)找出那些不在继续使用的变量,然后释放其内存。非实时,周期性执行

function fn1(){
	var obj = {name: 'leilei', age: 10};
}
function fn2(){
	var obj = {name: 'leilei', age: 10};
	return obj;
}
var a = fn1();
var b = fn2();

//这里fn1中定义的obj为局部变量,当调用结束后,出了fn1的环境,那么该块内存会被js引擎中的垃圾回收器自动释放。
//fn2被调用的过程中,返回的对象被全局变量b所指向,所以该块内存不会被释放

垃圾回收策略:标记清除和引用计数

  1. 标记清除
    定义:当变量进入环境时,将变量标记“进入环境”,当变量离开环境时,标记为“离开环境”。某一个时刻,垃圾回收器会过滤掉环境中的变量,以及被环境变量引用的变量,剩下的就是被视为准备回收的变量。
    目前为止,IE、Firefox、Opera、Chrome、Safari的js实现使用的都是标记清除的垃圾回收策略或类似的策略,只不过垃圾收集的时间间隔互不相同。
  2. 引用计数
    定义:跟踪记录每个值被引用的次数
    基本原理:就是变量的引用次数,被引用一次则加1,当这个引用计数为0时,被视为准备回收的对象。

内存管理

  1. 什么时候触发垃圾回收
    IE6的垃圾回收是根据内存分配量运行的,当环境中的变量,对象,字符串达到一定数量时触发垃圾回收。垃圾回收器一直处于工作状态,严重影响浏览器性能。
    IE7中,垃圾回收器会根据内存分配量与程序占用内存的比例进行动态调整,开始回收工作。
  2. 合理的GC方案:a.遍历所有可访问的对象;b.回收已不可访问的对象
  3. GC缺陷:停止响应其他操作
  4. GC优化策略:a.分代回收(Generation GC)b.增量GC

开发中遇到的内存泄露情况
定义:内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。浏览器也是采用自动垃圾回收方法管理内存,但由于浏览器垃圾回收方法有bug,会产生内存泄露
泄露的几种情况:

  1. 当页面中元素被移除或替换时,若元素绑定的事件仍没被移除,在IE中不会作出恰当处理,此时要先手工移除事件,不然会存在内存泄露。
<div id="myDiv">
	<input type="button" value="Click Me" id="myBtn">
</div>
var btn = document.getElementById("myBtn");
btn.onclick = function () {
	document.getElementById("myDiv").innerHTML = "Processing...";
}
/*
这里执行点击事件后,input被替换了
*/
var btn = document.getElementById("myBtn");
btn.onclick = function () {
	btn.onclick = null;
	document.getElementById("myDiv").innerHTML = "Processing...";
}
//b.由于函数内定义函数,并且内部函数-事件回调的引用外暴了,形成了闭包。闭包可以维持函数内部变量,使其得不到释放。
function bingEvent(){
	var obj = document.createElement("XXX");
	obj.onclick = function(){
		//Even if it's a empty function
	}
}
//解决方法
function bingEvent(){
	var obj = document.createElement("XXX");
	obj.onclick = function(){
		//Even if it's a empty function
	}
	obj = null;
}

12.JavaScript面向对象中继承实现

面向对象的基本特征有:封闭、继承、多态
在JavaScript中实现继承的方法:

  • 原型链(prototype chaining)
  • call()/apply()
  • 混合方式(prototype和call()/apply()结合)
  • 对象冒充

继承的方法:

  1. prototype原型链
function teacher(name){
	this.name = name;
}
teacher.prototype.sayName = function(){
	console.log("name is " + this.name);
}
var teacher1 = new teacher("leilei");
teacher1.sayName();

function student(name){
	this.name = name;
}
student.prototype = new teacher();
var student1 = new student("xiaolei");
student1.sayName();
//name is leilei
//name is xiaolei
  1. call()/apply()方法
function teacher(name, age){
	this.name = name;
	this.age = age;
	this.sayHi = function(){
		alert("name: " + this.name + ", age: " + this.age);
	}
}
function student(){
	var args = arguments;
	teacher.apply(this, arguments);
	//teacher.call(this, args[0], args[1]);
}
var teacher1 = new teacher('leilei',21);
teacher1.sayHi();
var student1 = new student('xiaolei', 22);
student1.sayHi();
  1. 混合方法prototype+call/apply
function teacher(name, age){
	this.name = name;
	this.age = age;
}
teacher.prototype.sayHello = function(){
	alert("name: " + this.name + ", age: " + this.age);
}
function student(){
	var args = arguments;
	teacher.call(this, args[0], args[1]);
}
student.prototype = new teacher();
var student1 = new student("xiaolei", 22);
student1.sayHello();
  1. 对象冒充
function teacher(name, age){
	this.name = name;
	this.age = age;
	this.showInfo = function(){
		alert("name: " + this.name + ", age: " +this.age);
	}
}
function student(name, age){
	this.student = teacher;
	this.student(name, age);
	delete this.student;
}
var student1 = new student("xiaolei", 22);
student1.showInfo();

13.判断一个字符串中出现次数最多的字符,统计这个次数

var str="asdfsasasaasssaaaaaaa";
var charCount = {};
for(var i=0; i<str.length; i++){
	if(!charCount[str.charAt(i)]){
		charCount[str.charAt(i)] = 1;
	} else {
		charCount[str.charAt(i)]++;
	}
}
var iMax = 0;
var iIndex = '';
for(var i in charCount){
	if(charCount[i] > iMax) {
		iMax = charCount[i];
		iIndex = i;
	}
}
console.log(charCount);
console.log(iIndex + "出现次数最多:" + iMax + "次;")

14. Array数组对象

14.1 Array相关的属性和方法
Array对象属性
constructor 返回创建对象的数组函数的引用
length 设置或返回数组中元素的数目
prototype 增加能力对对象添加属性和方法

Array对象方法
concat()连接两个或更多的数组,并返回结果
join()把数组的所有元素放入一个字符串。元素通过指定的分隔符进行分隔
pop()删除并返回数组的最后一个元素
shift()删除并返回数组的第一个元素
push()向数组的末尾添加一个或多个元素,并返回新的长度
unshift()向数组的开头添加一个或多个元素,并返回新的长度
reverse()颠倒数组中元素的顺序
slice()从某个已有的数组返回选定的元素
sort()对数组的元素进行排序
splice()删除元素,并向数组添加新元素
toSource()返回该对象的源代码
toString()把数组转换为字符串,并返回结果
toLocalString()把数组转换为本地数组,并返回结果
valueOf()返回数组对象的原始值

14.2 去除数组中的重复元素

//方法一
var arr = [0,2,2,3,3,4,5,6];
var obj = {};
var tmp = [];
for(var i=0; i< arr.length; i++){
	if(!obj[arr[i]]){
		obj[arr[i]]=1;
		tmp.push(arr[i]);
	}
}
console.log(tmp);
//方法二
var arr = [0,2,2,3,3,4,5,6];
var arr2 = []
for(var i=0; i < arr.length;i++){
	if(arr2.indexOf(arr[i])<0){
		arr2.push(arr[i]);
	}
}
console.log(arr2);
//方法三
var arr = [0,2,2,3,3,4,5,6];
var arr2 = arr.filter(function(element,index,self){
	return self.indexOf(emlement) === index;
});
console.log(arr2);

15.IE与FF脚本兼容性问题

  • window.event表示当前的事件对象,IE有这个对象,FF没有,FF通过给事件处理函数传递事件对象
  • 获取事件源:IE用srcElement获取事件源,而FF用target获取事件源
  • 添加,去除事件
IE:element.attachEvent("onclick",function)
	element.detachEvent("onclick",function)
FF:element.addEventListener("click",function,true)
	element.removeEventListener("click",function,true)
  • 获取标签的自定义属性
IE:div.value或div["value"]
FF:div.getAttribute("value")

document.getElementsByName()和document.all[name]
//IE:document.getElementsByName()和document.all[name]均不能获取div元素
//FF:可以
input.type的属性
/*IE:input.type只读
FF:input.type可读写
*/
innerText textContent outerHTML
/*IE:支持innerText,outerHTML
FF:支持textContent*/
是否可用id代替HTML元素
/*IE:可以用id来代替HTML元素
FF:不可用
*/

16.规避JavaScript多人开发函数重名问题

  • 可以开发前端规定命名规范,根据不同开发人员开发的功能在函数前加前缀
  • 将每个开发人员的函数封装到类中,调用的时候就调用类的函数,即使函数重名只要类名不重复就ok

17.FF下实现outerHTML

FF:支持textContent,但不支持innerHTML和outerHTML
思路:先添加一个新元素A,克隆需要获取outerHTML的元素,将这个元素append到新的A元素中,然后获取A的innerHTML

<div id="a"><span>TEXT</span></div>
function getOuterHTML(id){
	var el = document.getElementById(id);
	var newNode = document.createElement("div");
	document.appendChild(newNode);
	var clone = el.cloneNode(true);
	newNode.appendChild(clone);
	alert(newNode.innerHTML);
	document.removeChild(newNode);
}
getOuterHTML("a");

18.求一个字符串的字节长度

假设:一个英文字符占用一个字节,一个中文字符占用两个字节

function getBytes(str){
	var length = str.length;
	var bytesLen = length;
	for(var i=0;i<length;i++){
		if(str.charCodeAt(i) > 255){
			bytesLen ++;
		}
	}
	return bytesLen;
}
console.log(getBytes("字符串222"));

19.去掉一个数组的重复数字的方法

var arr = [0,2,3,2,0,4];
Array.prototype.unique = function(){
	var _this = this;
	var len = _this.length;
	var arr2 = [];
	for(var i=0;i<len;i++){
		if(arr2.indexOf(_this[i]) < 0){
			arr2.push(_this[i]);
		}
	}
	return arr2;
}
alert(arr.unique());

20.如何显示和隐藏一个dom元素el

el.style.display = "";
el.style.display = "none";

21.JavaScript中如何检测一个变量是String类型

var str = "abcsdea";
function getStr(str){
	if(typeof str == "string" || str.constructor == String){
		return true;
	}
}
getStr(str);

22.实现一个计算当年还剩多少时间的倒数计时程序

function timeCount(){
	var date = new Date();
	var year = date.getFullYear();
	var date2 = new Date(year, 12, 31, 23, 59, 59);
	var time = (date2 - date)/1000;
	var day = Math.floor(time/(24*60*60));
	var hour = Math.floor(time%(24*60*60)/(60*60));
	var miniute = Math.floor(time%(24*60*60)%(60*60)/60);
	var second = Math.floor(time%(24*60*60)%(60*60)%60);
	var str = year + "年还剩"+day+"天"+hour+"时"+miniute+"分"+second+"秒";
	console.log(str);
}
window.setInterval("timeCount()", 1000);

23.clone,将button1移动到button2后面

<input type="button" id="button1" value="1" onclick="removeBtn(this)">
<input type="button" id="button2" value="1">
function removeBtn(obj){
	var clone = cloneNode(obj);
	var parent = obj.parentNode;
	parent.appendChild(clone);
	parent.removeChild(obj);
}

24.鼠标点击页面中的任意标签,alert该标签的名称(注意兼容)

document.onclick = function(evt){
	var e = window.event || evt;
	var tag = e["target"] || e["srcElement"]; //ie支持srcElement,FF支持target
	alert(tag.tagName);
}

25.编写一个JavaScript函数parseQueryString,将URL参数解析为一个对象

function parseQueryString(url){
	var params = {}
	var arr = url.split("?");
	if(arr.length <= 1){ return params;}
	arr = arr[1].split("&");
	for(var i=0;i<arr.length;i++){
		var a = arr[i].split("=");
		params[a[0]]=a[1];
	}
	return params;
}
var url = "http://witmax.cn/index.php?key0=0&key1=1&key2=2";
var ps = parseQueryString(url);
console.log(ps);

26.ajax是什么,ajax的交互模型,同步和异步的区别,如何解决跨域

Ajax是多种技术组合起来的一种浏览器和服务器交互技术,基本思想是允许一个互联网浏览器向一个远程页面/服务做异步的http调用,并且用收到的数据来更新一个当前web页面而不必刷新整个页面。提升用户体验。
包含技术:
XHTML,CSS,DOM,JavaScript,XML,XMLHttpRequest

同步:脚本会停留并等待服务器发送回复然后再继续
异步:脚本允许页面继续其进程并处理可能的回复

27.点击ul的每一列,alert其index

<ul id="test">
	<li>第一条</li>
	<li>第二条</li>
	<li>第三条</li>
</ul>
(function retuIndex(){
	var index = 0;
	var ul = document.getElementById("test");
	var obj = {};
	for(var i=0;i<ul.childNodes.length;i++){
		if(ul.childNodes[i].nodeName.toLowerCase() == "li"){
			var li = ul.childNodes[i];
			li.onclick = function(){
				index++;
				alert(index);
			}
		}
	}

})();

28.异步加载Js的方法,两种

a.defer,只支持IE
b.async
c.创建script,插入到DOM中,加载完毕后callBack

function loadScript(url, callback){
	var script = document.createElement("script");
	script.type = "text/javascript";
	if(script.readyState){ //IE
		script.onreadystatechange = function(){
			if(script.readyState == "loaded" || script.readyState == "complete"){
				script.readystatechange = null;
				callback();
			}
		};
	} else { //Others: Firefox, Safari, Chrome, and Opera
		script.onload = function(){
			callback();
		};

	}
	script.src = url;
	document.body.appendChild(script);
}

25.设计一套方案,用于确保页面中JS加载完全

var n = document.createElement("script");
n.type = "text/javascript";
//以上省略部分代码
//ie支持script的readystatechange属性
if(ua.ie){
   n.onreadystatechange = function(){
       var rs = this.readyState;
       if('loaded' === rs || 'complete'===rs){
           n.onreadystatechange = null;
           f(id,url); //回调函数
       }
};
//省略部分代码
//safari 3.x supports the load event for script nodes(DOM2)
   n.addEventListener('load',function(){
       f(id,url);
   });
//firefox and opera support onload(but not dom2 in ff) handlers for
//script nodes. opera, but no ff, support the onload event for link
//nodes.
}else{
   n.onload = function(){
       f(id,url);
   };
}

26.如何添加html元素的事件

  • 为HTML元素的事件属性赋值
  • 在JS中使用ele.on*** = function() {…}
  • 使用DOM2的添加事件的方法 addEventListener或attachEvent

27.documen.write和 innerHTML的区别

  • document.write只能重绘整个页面
  • innerHTML可以重绘页面的一部分

28.多浏览器检测通过什么?

  • navigator.userAgent
  • 不同浏览器的特性,如addEventListener*/

29.js的基础对象有那些, window和document的常用的方法和属性列出来

  1. js的基础对象:String,Number,Boolean
  2. Window
    方法:setInterval,setTimeout,clearInterval,clearTimeout,alert,confirm,open
    属性:name,parent,screenLeft,screenTop,self,top,status
    Document
    方法:createElement,execCommand,getElementById,getElementsByName,getElementByTagName,write,writeln
    属性:cookie,doctype,domain,documentElement,readyState,UR
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值