前端面试之Javascript基础113+【二】
js基础
一、JS基础
- javascript的typeof返回哪些数据类型
alert(typeof [1, 2]); //object
alert(typeof 'leipeng'); //string
var i = true;
alert(typeof i); //boolean
alert(typeof 1); //number
var a;
alert(typeof a); //undefined
function a(){;};
alert(typeof a) //function
- 例举3种强制类型转换和2种隐式类型转换?
强制(parseInt(),parseFloat(),Number())
隐式(== ,!!)
- split() 、join() 的区别
前者是切割成数组的形式,后者是将数组转换成字符串
- 数组方法pop() push() unshift() shift()
push()尾部添加 pop()尾部删除
unshift()头部添加 shift()头部删除
map() : 遍历数组中的元素, 返回一个新数组(包含回调函数返回的数据)
filter():遍历数组中的元素, 返回一个新数组(包含回调函数返回true的元素)
- 事件绑定和普通事件有什么区别
普通添加事件的方法:
var btn = document.getElementById("hello");
btn.onclick = function(){
alert(1);
}
btn.onclick = function(){
alert(2);
}
执行上面的代码只会alert 2
事件绑定方式添加事件:
var btn = document.getElementById("hello");
btn.addEventListener("click",function(){
alert(1);
},false);
btn.addEventListener("click",function(){
alert(2);
},false);
执行上面的代码会先alert 1 再 alert 2
普通添加事件的方法不支持添加多个事件,最下面的事件会覆盖上面的,而事件绑定(addEventListener)方式添加事件可以添加多个。
addEventListener不兼容低版本IE
普通事件无法取消
addEventLisntener还支持事件冒泡+事件捕获
- IE和DOM事件流的区别
1.执行顺序不一样、
2.参数不一样
3.事件加不加on
4.this指向问题
- IE和标准下有哪些兼容性的写法
var ev = ev || window.event
document.documentElement.clientWidth || document.body.clientWidth
var target = ev.srcElement||ev.target
- call和apply的区别
功能一样, 都是将当前函数作为指定对象的方法执行, 即函数中的this是指定对象
call(thisObj,arg1,arg2…) //将所有参数一个一个传递进去
apply(thisObj,[argArray]) //将所有参数放在数组中传入
- Worker继承Person的方法
//使用构造函数+原型的组合模式
function Person( age, name ){
this.age = age;
this.name = name;
}
Person.prototype.show = function(){
alert('父级方法');
}
function Worker(age,name,job){
Person.apply( this, arguments);
this.job = job;
}
Worker.prototype = new Person();
var Person = new Person(14,'张三 ');
var Worker = new Worker (25,'李四','程序员');
- 如何阻止事件冒泡和事件默认行为
//阻止事件冒泡
if(typeof ev.stopPropagation=='function') { //标准的
ev.stopPropagation();
} else { //非标准IE
window.event.cancelBubble = true;
}
//阻止事件默认行为
return false
- 添加 删除 替换 插入到某个元素的方法
element.appendChild()
element.insertBefore()
element.replaceChild()
element.removeChild()
- javascript的内置对象和宿主对象
内置对象为Object, Array, Function, Date, Math等
宿主为浏览器自带的window 等
- window.onload 和document ready的区别
window.onload 是在dom文档树加载完和所有文件加载完之后执行一个函数document.ready原生中没有这个方法,jquery中有 $().ready(function),在dom文档树加载完之后执行一个函数(注意,这里面的文档树加载完不代表全部文件加载完)。
(document).ready可以出现多次
- ”==”和“===”的不同
前者会自动转换类型
后者不会
- 浏览器的同源策略
一段脚本(ajax)只能读取来自于同一来源的窗口和文档的属性,这里的同一来源指的是主机名、协议和端口号的组合
- JavaScript是一门什么样的语言,它有哪些特点?
javaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML网页上使用,用来给HTML网页增加动态功能。JavaScript兼容于ECMA标准,因此也称为ECMAScript。
基本特点
- 是一种解释性脚本语言(代码不进行预编译)。
- 主要用来向HTML(标准通用标记语言下的一个应用)页面添加交互行为。
- 可以直接嵌入HTML页面,但写成单独的js文件有利于结构和行为的分离。
跨平台特性,在绝大多数浏览器的支持下,可以在多种平台下运行(如Windows、Linux、Mac、Android、iOS等)。
- JavaScript的数据类型都有什么?
基本数据类型:String,boolean,Number,Undefined, Null
引用数据类型:Object, Array, Function
那么问题来了,如何判断某变量是否为数组数据类型?
方法一.判断其是否具有“数组性质”,如slice()方法。可自己给该变量定义slice方法,故有时会失效
方法二.obj instanceof Array 在某些IE版本中不正确
方法三.方法一二皆有漏洞,在ECMA Script5中定义了新方法Array.isArray(), 保证其兼容性,最好的方法如下:
if(typeof Array.isArray==="undefined")
{
Array.isArray = function(arg){
return Object.prototype.toString.call(arg)==="[object Array]"
};
}
- 已知ID的Input输入框,希望获取这个输入框的输入值,怎么做?(不使用第三方框架)
document.getElementById(ID).value
- 希望获取到页面中所有的checkbox怎么做?(不使用第三方框架)
var domList = document.getElementsByTagName(‘input’)
var checkBoxList = [];
var len = domList.length; //缓存到局部变量
for (var i=0;i<len;i++) {
if (domList[i].type == ‘checkbox’) {
checkBoxList.push(domList[i]);
}
}
- 设置一个已知ID的DIV的html内容为xxxx,字体颜色设置为黑色(不使用第三方框架)
var dom = document.getElementById(“ID”);
dom.innerHTML = “xxxx”
dom.style.color = “#000”
- 当一个DOM节点被点击时候,我们希望能够执行一个函数,应该怎么做?
直接在DOM里绑定事件:
在JS里通过onclick绑定:xxx.onclick = test
通过事件添加进行绑定:addEventListener(xxx, ‘click’, test)
那么问题来了,Javascript的事件流模型都有什么?
“事件冒泡”:事件开始由最具体的元素接受,然后逐级向上传播
“事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的
“DOM事件流”:三个阶段:事件捕捉,目标阶段,事件冒泡
- 看下列代码输出为何?解释原因。
var a;
alert(typeof a); // undefined
alert(b); // 报错
解释:Undefined是一个只有一个值的数据类型,这个值就是“undefined”,在使用var声明变量但并未对其赋值进行初始化时,这个变量的值就是undefined。而b由于未声明将报错。注意未申明的变量和声明了未赋值的是不一样的。
- 看下列代码,输出什么?解释原因。
var a = null;
alert(typeof a); //object
解释:null是一个只有一个值的数据类型,这个值就是null。表示一个空指针对象,所以用typeof检测会返回”object”。
看下列代码,输出什么?解释原因。
var undefined;
undefined == null; // true
1 == true; // true
2 == true; // false
0 == false; // true
0 == ''; // true
NaN == NaN; // false
[] == false; // true
[] == ![]; // true
undefined与null相等,但不恒等(===)
一个是number一个是string时,会尝试将string转换为number
尝试将boolean转换为number,0或1
尝试将Object转换成number或string,取决于另外一个对比量的类型
所以,对于0、空字符串的判断,建议使用 “===” 。“===”会先判断两边的值类型,类型不匹配时为false。
那么问题来了,看下面的代码,输出什么,foo的值为什么?
var foo = "11"+2-"1";
console.log(foo);
console.log(typeof foo);
执行完后foo的值为111,foo的类型为String。
- 看代码给答案。
var a = new Object();
a.value = 1;
b = a;
b.value = 2;
alert(a.value);
答案:2(考察引用数据类型细节)
- 已知数组var stringArray = [“This”, “is”, “Baidu”, “Campus”],Alert出”This is Baidu Campus”。
alert(stringArray.join(“”))
- 已知有字符串foo=”get-element-by-id”,写一个function将其转化成驼峰表示法”getElementById”。
function combo(msg){
var arr=msg.split("-");
for(var i=1;i<arr.length;i++){
arr[i]=arr[i].charAt(0).toUpperCase()+arr[i]
.substr(1,arr[i].length-1);
}
msg=arr.join("");
return msg;
}
- var numberArray = [3,6,2,4,1,5]; (考察基础API)
- 实现对该数组的倒排,输出[5,1,4,2,6,3]
numberArray.reverse() - 实现对该数组的降序排列,输出[6,5,4,3,2,1]
numberArray.sort(function(a,b){return b-a})
- 输出今天的日期,以YYYY-MM-DD的方式,比如今天是2014年9月26日,则输出2014-09-26
var d = new Date();
// 获取年,getFullYear()返回4位的数字
var year = d.getFullYear();
// 获取月,月份比较特殊,0是1月,11是12月
var month = d.getMonth() + 1;
// 变成两位
month = month < 10 ? '0' + month : month;
// 获取日
var day = d.getDate();
day = day < 10 ? '0' + day : day;
alert(year + '-' + month + '-' + day);
- 将字符串”{KaTeX parse error: Expected 'EOF', got '}' at position 3: id}̲</td><td>{name}”中的{KaTeX parse error: Expected 'EOF', got '}' at position 3: id}̲替换成10,{name}替换成Tony (使用正则表达式)
"<tr><td>{$id}</td><td>{$id}_{$name}</td></tr>".replace(/{\$id}/g, '10').replace(/{\$name}/g, 'Tony');
- 为了保证页面输出安全,我们经常需要对一些特殊的字符进行转义,请写一个函数escapeHtml,将<, >, &, “进行转义
function escapeHtml(str) {
return str.replace(/[<>”&]/g, function(match) {
switch (match) {
case “<”:
return “<”;
case “>”:
return “>”;
case “&”:
return “&”;
case “\””:
return “"”;
}
});
}
- foo = foo||bar ,这行代码是什么意思?为什么要这样写?
如果foo存在,值不变,否则把bar的值赋给foo。
短路表达式:作为”&&”和”||”操作符的操作数表达式,这些表达式在进行求值时,只要最终的结果已经可以确定是真或假,求值过程便告终止,这称之为短路求值。
- 看下列代码,将会输出什么?(变量声明提升)
var foo = 1;
(function(){
console.log(foo);
var foo = 2;
console.log(foo);
})()
答案:输出undefined 和 2。上面代码相当于:
var foo = 1;
(function(){
var foo;
console.log(foo); //undefined
foo = 2;
console.log(foo); // 2;
})()
函数声明与变量声明会被JavaScript引擎隐式地提升到当前作用域的顶部,但是只提升名称不会提升赋值部分。
- 用js实现随机选取10–100之间的10个数字,存入一个数组,并排序。
function randomNub(aArray, len, min, max) {
if (len >= (max - min)) {
return '超过' + min + '-' + max + '之间的个数范围' + (max - min - 1) + '个的总数';
}
if (aArray.length >= len) {
aArray.sort(function(a, b) {
return a - b
});
return aArray;
}
var nowNub = parseInt(Math.random() * (max - min - 1)) + (min + 1);
for (var j = 0; j < aArray.length; j++) {
if (nowNub == aArray[j]) {
randomNub(aArray, len, min, max);
return;
}
}
aArray.push(nowNub);
randomNub(aArray, len, min, max);
return aArray;
}
var arr=[];
randomNub(arr,10,10,100);
- 把两个数组合并,并删除第二个元素。
var array1 = ['a','b','c'];
var bArray = ['d','e','f'];
var cArray = array1.concat(bArray);
cArray.splice(1,1);
- 怎样添加、移除、移动、复制、创建和查找节点(原生JS,实在基础,没细写每一步)
1)创建新节点
createDocumentFragment() //创建一个DOM片段
createElement() //创建一个具体的元素
createTextNode() //创建一个文本节点
2)添加、移除、替换、插入
appendChild() //添加
removeChild() //移除
replaceChild() //替换
insertBefore() //插入
3)查找
getElementsByTagName() //通过标签名称
getElementsByName() //通过元素的Name属性的值
getElementById() //通过元素Id,唯一性
- 有这样一个URL:http://item.taobao.com/item.htm?a=1&b=2&c=&d=xxx&e,请写一段JS程序提取URL中的各个GET参数(参数名和参数个数不确定),将其按key-value形式返回到一个json结构中,如{a:’1′, b:’2′, c:”, d:’xxx’, e:undefined}。
function serilizeUrl(url) {
var urlObject = {};
if (/\?/.test(url)) {
var urlString = url.substring(url.indexOf("?") + 1);
var urlArray = urlString.split("&");
for (var i = 0, len = urlArray.length; i < len; i++) {
var urlItem = urlArray[i];
var item = urlItem.split("=");
urlObject[item[0]] = item[1];
}
return urlObject;
}
return null;
}
- 正则表达式构造函数var reg=new RegExp(“xxx”)与正则表达字面量var reg=//有什么不同?匹配邮箱的正则表达式?
当使用RegExp()构造函数的时候,不仅需要转义引号(即\”表示”),并且还需要双反斜杠(即\\表示一个\)。使用正则表达字面量的效率更高。
邮箱的正则匹配:
var regMail = /^([a-zA-Z0-9_-])[email protected]([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/;
- 看下面代码,给出输出结果。
for(var i=1;i<=3;i++){
setTimeout(function(){
console.log(i);
},0);
};
答案:4 4 4。
原因:回调函数是在for结束之后才运行的。追问,如何让上述代码输出1 2 3?
for(var i=1;i<=3;i++){
setTimeout((function(j){ //改成立即执行函数
console.log(j);
})(i),0);
};
- 写一个function,清除字符串前后的空格。(兼容所有浏览器)
if (!String.prototype.trim) {
String.prototype.trim = function() {
return this.replace(/^\s+/, "").replace(/\s+$/,"");
}
}
//测试
var str = " \t\n test string ".trim();
alert(str == "test string"); // alerts "true"
- Javascript中, 以下哪条语句一定会产生运行错误?
var _变量=NaN; B、var 0bj = []; C、var obj = //; D、var obj = {}; 答案( B C )
- 以下两个变量a和b,a+b的哪个结果是NaN? 答案( AC )
A、var a=undefined; b=NaN
B、var a= ‘123’; b=NaN
C、var a =undefined , b =NaN
var a=NaN , b=‘undefined’
- var a=10; b=20; c=4; ++b+c+a++ 以下哪个结果是正确的?
A 34 B、35 C、36 D、37 答案( B )
- 下面的JavaScript语句中,( D )实现检索当前页面中的表单元素中的所有文本框,并将它们全部清空
A. for(vari=0;i< form1.elements.length;i++) {
if(form1.elements.type==”text”)
form1.elements.value=”";}
B. for(vari=0;i<document.forms.length;i++) {
if(forms[0].elements.type==”text”)
forms[0].elements.value=”";
}
C. if(document.form.elements.type==”text”)
form.elements.value=”";
D. for(vari=0;i<document.forms.length; i++){
for(var j=0;j<document.forms.elements.length; j++){
if(document.forms.elements[j].type==”text”)
document.forms.elements[j].value=”";
}
}
- 要将页面的状态栏中显示“已经选中该文本框”,下列JavaScript语句正确的是( A )
A. window.status=”已经选中该文本框”
B. document.status=”已经选中该文本框”
C. window.screen=”已经选中该文本框”
D. document.screen=”已经选中该文本框”
- 以下哪条语句会产生运行错误:(AD)
A.var obj = ();
B.var obj = [];
C.var obj = {};
D.var obj = //;
- 以下哪个单词不属于javascript保留字:(B)
A.with
B.parent
C.class
D.void
- 请选择结果为真的表达式:(C)
A.null instanceof Object
B.null === undefined
C.null == undefined
D.NaN == NaN
- 分析代码,得出正确的结果。
var a=10, b=20 , c=30;
++a;
a++;
e=++a + (++b) + (c++) + a++;
alert(e);
弹出提示对话框:77
- 写出函数DateDemo的返回结果,系统时间假定为今天
function DateDemo(){
var d, s="今天日期是:";
d = new Date();
s += d.getMonth() +1+ "/";
s += d.getDate() + "/";
s += d.getFullYear();
return s;
}
结果:今天日期是:7/21/2016
- 写出程序运行的结果?
for(i=0, j=0; i<10, j<6; i++, j++){
k = i + j;}
结果:10
- 阅读以下代码,请分析出结果:
var arr = new Array(1 ,3 ,5);
arr[4]='z';
arr2 = arr.reverse();
arr3 = arr.concat(arr2);
alert(arr3);
弹出提示对话框:z,,5,3,1,z,,5,3,1
- 写出简单描述html标签(不带属性的开始标签和结束标签)的正则表达式,并将以下字符串中的html标签去除掉
var str = “<div>这里是div<p>里面的段落</p></div>”;
<scripttype=”text/javascript”>
var reg = /<\/?\w+\/?>/gi;
var str = “<div>这里是div<p>里面的段落</p></div>”;
alert(str.replace(reg,”"));
</script>
截取字符串abcdefg的efg
alert('abcdefg'.substring(4));
- 列举浏览器对象模型BOM里常用的至少4个对象,并列举window对象的常用方法至少5个
对象:window, document, location, screen, history, navigator
方法:alert(), confirm(), prompt(), open(), close()
- 简述列举文档对象模型DOM里document的常用的查找访问节点的方法并做简单说明
document.getElementById 根据元素id查找元素
document.getElementByName 根据元素name查找元素
document.getElementTagName 根据指定的元素名查找元素
- 简述创建函数的几种方式
第一种(函数声明):
function sum1(num1,num2){
return num1+num2;
}
第二种(函数表达式):
var sum2 = function(num1,num2){
return num1+num2;
}
第三种(函数对象方式):
var sum3 = new Function("num1","num2","return num1+num2");
- Javascript创建对象的几种方式?
1、var obj = {};(使用json创建对象)
如:obj.name = '张三';
obj.action = function ()
{
alert('吃饭');
};
2、var obj = new Object();(使用Object创建对象)
如:obj.name = '张三';
obj.action = function ()
{
alert('吃饭');
};
3、通过构造函数创建对象。
(1)、使用this关键字
如:var obj = function (){
this.name ='张三';
this.age = 19;
this.action = function ()
{
alert('吃饭');
};
}
(2)、使用prototype关键字
如:function obj (){}
obj.prototype.name ='张三';
obj.prototype.action=function ()
{
alert('吃饭');
};
4、使用内置对象创建对象。
如:var str = new String("实例初始化String");
var str1 = "直接赋值的String";
var func = new Function("x","alert(x)");//示例初始化func
var obj = new Object();//示例初始化一个Object
- iframe的优缺点?
优点:
- 解决加载缓慢的第三方内容如图标和广告等的加载问题
- Security sandbox
- 并行加载脚本
缺点: - iframe会阻塞主页面的Onload事件
- 即时内容为空,加载也需要时间
- 没有语意
- 请你谈谈Cookie的弊端?
- Cookie数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。
- 安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
- 有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。
- js延迟加载的方式有哪些?
- defer和async
- 动态创建DOM方式(创建script,插入到DOM中,加载完毕后callBack)
- 按需异步载入js
- 哪些操作会造成内存泄漏?
内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。
- setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
- 闭包
- 控制台日志
- 循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
- 判断一个字符串中出现次数最多的字符,统计这个次数
var str = 'asdfssaaasasasasaa';
var json = {};
for (var i = 0; i < str.length; i++) {
if(!json[str.charAt(i)]){
json[str.charAt(i)] = 1;
}else{
json[str.charAt(i)]++;
}
};
var iMax = 0;
var iIndex = '';
for(var i in json){
if(json[i]>iMax){
iMax = json[i];
iIndex = i;
}
}
alert('出现次数最多的是:'+iIndex+'出现'+iMax+'次');
- 写一个获取非行间样式的函数
function getStyle(obj,attr,value)
{
if(!value)
{
if(obj.currentStyle)
{
return obj.currentStyle(attr);
}
else{
obj.getComputedStyle(attr,false);
}
}
else
{
obj.style[attr] = value;
}
}
- 闭包是什么,有什么特性,对页面有什么影响
答:当内部函数使用了外部函数的局部变量时, 产生的一个对象(包含了所有使用了的变量)
作用: 在函数执行完后, 局部变量还会存在
function outer(){
var num = 1;
function inner(){
var n = 2;
alert(n + num);
}
return inner;
}
var r = outer();
r();
- 解释jsonp的原理,以及为什么不是真正的ajax
动态创建script标签,回调函数
Ajax是页面无刷新请求数据操作
- 字符串反转,如将 ‘12345678’ 变成 ‘87654321’
//思路:先将字符串转换为数组 split(),利用数组的反序函数 reverse()颠倒数组,再利用 jion() 转换为字符串
var str = '12345678';
str = str.split('').reverse().join('');
将数字 12345678 转化成 RMB形式 如: 12,345,678
//思路:先将数字转为字符, str= str + '' ;
//利用反转函数,每三位字符加一个 ','最后一位不加; re()是自定义的反转函数,最后再反转回去!
function re(str) {
str += '';
return str.split("").reverse().join("");
}
function toRMB(num) {
var tmp='';
for (var i = 1; i <= re(num).length; i++) {
tmp += re(num)[i - 1];
if (i % 3 == 0 && i != re(num).length) {
tmp += ',';
}
}
return re(tmp);
}
- 生成5个不同的随机数;
//思路:5个不同的数,每生成一次就和前面的所有数字相比较,如果有相同的,则放弃当前生成的数字!
var num1 = [];
for(var i = 0; i < 5; i++){
num1[i] = Math.floor(Math.random()*10) + 1; //范围是 [1, 10]
for(var j = 0; j < i; j++){
if(num1[i] == num1[j]){
i--;
}
}
}
- 去掉数组中重复的数字 方法一;
//思路:每遍历一次就和之前的所有做比较,不相等则放入新的数组中!
//这里用的原型 个人做法;
Array.prototype.unique = function(){
var len = this.length,
newArr = [],
flag = 1;
for(var i = 0; i < len; i++, flag = 1){
for(var j = 0; j < i; j++){
if(this[i] == this[j]){
flag = 0; //找到相同的数字后,不执行添加数据
}
}
flag ? newArr.push(this[i]) : '';
}
return newArr;
}
方法二:
var arr=[1,2,3,3,4,4,5,5,6,1,9,3,25,4];
Array.prototype.unique2 = function()
{
var n = []; //一个新的临时数组
for(var i = 0; i < this.length; i++) //遍历当前数组
{
//如果当前数组的第i已经保存进了临时数组,那么跳过,
//否则把当前项push到临时数组里面
if (n.indexOf(this[i]) == -1) n.push(this[i]);
}
return n;
}
var newArr2=arr.unique2(arr);
alert(newArr2); //输出1,2,3,4,5,6,9,25
阶乘函数;
//原型方法
Number.prototype.N = function(){
var re = 1;
for(var i = 1; i <= this; i++){
re *= i;
}
return re;
}
var num = 5;
alert(num.N());
- javascript 中的垃圾回收机制?
在Javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收。如果两个对象互相引用,而不再 被第3者所引用,那么这两个互相引用的对象也会被回收。因为函数a被b引用,b又被a外的c引用,这就是为什么 函数a执行后不会被回收的原因。
- 看题做答:
function f1(){
var tmp = 1;
this.x = 3;
console.log(tmp); //A
console.log(this.x); //B
}
var obj = new f1(); //1
console.log(obj.x) //2
console.log(f1()); //3
这道题让我重新认识了对象和函数,首先看代码(1),这里实例话化了 f1这个类。相当于执行了 f1函数。所以这个时候 A 会输出 1, 而 B 这个时候的 this 代表的是 实例化的当前对象 obj B 输出 3.。 代码(2)毋庸置疑会输出 3, 重点 代码(3)首先这里将不再是一个类,它只是一个函数。那么 A输出 1, B呢?这里的this 代表的其实就是window对象,那么this.x 就是一个全局变量 相当于在外部 的一个全局变量。所以 B 输出 3。最后代码由于f没有返回值那么一个函数如果没返回值的话,将会返回 underfined ,所以答案就是 : 1, 3, 3, 1, 3, underfined 。
下面输出多少?
var o1 = new Object();
var o2 = o1;
o2.name = "CSSer";
console.log(o1.name);
如果不看答案,你回答真确了的话,那么说明你对javascript的数据类型了解的还是比较清楚了。js中有两种数据类型,分别是:基本数据类型和引用数据类型(object Array)。对于保存基本类型值的变量,变量是按值访问的,因为我们操作的是变量实际保存的值。对于保存引用类型值的变量,变量是按引用访问的,我们操作的是变量值所引用(指向)的对象。答案就清楚了: //CSSer;
再来一个
function changeObjectProperty (o) {
o.siteUrl = "http://www.csser.com/";
o = new Object();
o.siteUrl = "http://www.popcg.com/";
}
var CSSer = new Object();
changeObjectProperty(CSSer);
console.log(CSSer.siteUrl); // “http://www.csser.com/”
如果CSSer参数是按引用传递的,那么结果应该是"http://www.popcg.com/",但实际结果却仍是"http://www.csser.com/"。事实是这样的:在函数内部修改了引用类型值的参数,该参数值的原始引用保持不变。我们可以把参数想象成局部变量,当参数被重写时,这个变量引用的就是一个局部变量,局部变量的生存期仅限于函数执行的过程中,函数执行完毕,局部变量即被销毁以释放内存。
(补充:内部环境可以通过作用域链访问所有的外部环境中的变量对象,但外部环境无法访问内部环境。每个环境都可以向上搜索作用域链,以查询变量和函数名,反之向下则不能。)
- a输出多少?
var a = 6;
setTimeout(function () {
var a = 666;
alert(a); // 输出666,
}, 1000);
因为var a = 666;定义了局部变量a,并且赋值为666,根据变量作用域链,
全局变量处在作用域末端,优先访问了局部变量,从而覆盖了全局变量 。
var a = 6;
setTimeout(function () {
alert(a); // 输出undefined
var a = 666;
}, 1000);
因为var a = 666;定义了局部变量a,同样覆盖了全局变量,但是在alert(a);之前
a并未赋值,所以输出undefined。
var a = 6;
setTimeout(function(){
alert(a);
var a = 66;
}, 1000);
a = 666;
alert(a);
// 666, undefined;
记住: 异步处理,一切OK 声明提前
- 看程序,写结果
function setN(obj){
obj.name='屌丝';
obj = new Object();
obj.name = '腐女';
};
var per = new Object();
setN(per);
alert(per.name); //屌丝 内部
- 精度问题: JS 精度不能精确到 0.1 所以 。。。。同时存在于值和差值中
var n = 0.3,m = 0.2, i = 0.2, j = 0.1;
alert((n - m) == (i - j)); //false
alert((n-m) == 0.1); //false
alert((i-j)==0.1); //true
加减运算
alert('5'+3); //53 string
alert('5'+'3'); //53 string
alert('5'-3); //2 number
alert('5'-'3'); //2 number
- 为什么不能定义1px左右的div容器?
IE6下这个问题是因为默认的行高造成的,解决的方法也有很多,例如:
overflow:hidden | zoom:0.08 | line-height:1px
- 结果是什么?
function foo(){
foo.a = function(){alert(1)};
this.a = function(){alert(2)};
a = function(){alert(3)};
var a = function(){alert(4)};
};
foo.prototype.a = function(){alert(5)};
foo.a = function(){alert(6)};
foo.a(); //6
var obj = new foo();
obj.a(); //2
foo.a(); //1
输出结果
var a = 5;
function test(){
a = 0;
alert(a);
alert(this.a); //没有定义 a这个属性
var a;
alert(a)
}
test(); // 0, 5, 0
new test(); // 0, undefined, 0 //由于类它自身没有属性a, 所以是undefined
- 计算字符串字节数:
new function(s){
if(!arguments.length||!s) return null;
if(""==s) return 0;
var l=0;
for(var i=0;i<s.length;i++){
if(s.charCodeAt(i)>255) l+=2; else l+=1; //charCodeAt()得到的是unCode码
} //汉字的unCode码大于 255bit 就是两个字节
alert(l);
}("hello world!");
结果是:
var bool = !!2; alert(bool);//true;
双向非操作可以把字符串和数字转换为布尔值。
- 匹配输入的字符:第一个必须是字母或下划线开头,长度5-20
var reg = /^[a-zA-Z_][a-zA-Z0-9_]{5,20}/,
name1 = 'leipeng',
name2 = '0leipeng',
name3 = '你好leipeng',
name4 = 'hi';
alert(reg.test(name1));
alert(reg.test(name2));
alert(reg.test(name3));
alert(reg.test(name4));
- 如何在HTML中添加事件,几种方法?
1、标签之中直接添加 οnclick=“fun()”;
2、JS添加 Eobj.onclick = method;
3、绑定事件 IE: obj.attachEvent(‘onclick’, method);
FF: obj.addEventListener(‘click’, method, false);
BOM对象有哪些,列举window对象?
1、window对象 ,是JS的最顶层对象,其他的BOM对象都是window对象的属性;
2、document对象,文档对象;
3、location对象,浏览器当前URL信息;
4、navigator对象,浏览器本身信息;
5、screen对象,客户端屏幕信息;
6、history对象,浏览器访问历史信息;
- 请问代码实现 outerHTML
//说明:outerHTML其实就是innerHTML再加上本身;
Object.prototype.outerHTML = function(){
var innerCon = this.innerHTML, //获得里面的内容
outerCon = this.appendChild(innerCon); //添加到里面
alert(outerCon);
}
演示代码:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div id="outer">
hello
</div>
<script>
Object.prototype.outerHTML = function(){
var innerCon = this.innerHTML, //获得里面的内容
outerCon = this.appendChild(innerCon); //添加到里面
alert(outerCon);
}
function $(id){
return document.getElementById(id);
}
alert($('outer').innerHTML);
alert($('outer').outerHTML);
</script>
</body>
</html>
- JS中的简单继承 call方法!
//定义个父母类,注意:类名都是首字母大写的哦!
function Parent(name, money){
this.name = name;
this.money = money;
this.info = function(){
alert('姓名: '+this.name+' 钱: '+ this.money);
}
}
//定义孩子类
function Children(name){
Parent.call(this, name); //继承 姓名属性,不要钱。
this.info = function(){
alert('姓名: '+this.name);
}
}
//实例化类
var per = new Parent('parent', 800000000000);
var chi = new Children('child');
per.info();
chi.info();
- bind(), live(), delegate()的区别
bind: 绑定事件,对新添加的事件不起作用,方法用于将一个处理程序附加到每个匹配元素的事件上并返回jQuery对象。
live: 方法将一个事件处理程序附加到与当前选择器匹配的所有元素(包含现有的或将来添加的)的指定事件上并返回jQuery对象。
delegate: 方法基于一组特定的根元素将处理程序附加到匹配选择器的所有元素(现有的或将来的)的一个或多个事件上。
- 看下列代码输出什么?
var foo = "11"+2-"1";
console.log(foo);
console.log(typeof foo);
执行完后foo的值为111,foo的类型为Number。
看下列代码,输出什么?
var a = new Object();
a.value = 1;
b = a;
b.value = 2;
alert(a.value);
执行完后输出结果为2
- 怎样实现两栏等高?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="container" style="display: table;width: 100%;">
<div id="left" style="background-color: red;display: table-cell;">
内容<br/>
内容<br/>
内容<br/>
内容<br/>
内容<br/>
内容<br/>
</div>
<div style="display:table-cell;"></div>
<div id="right" style="background-color: blue;display: table-cell">
内容
</div>
</div>
</body>
</html>
- 使用js实现这样的效果:在文本域里输入文字时,当按下enter键时不换行,而是替换成“{{enter}}”,(只需要考虑在行尾按下enter键的情况).
<html>
<head>
<script>
function back(ele,event){
event = event || window.event;
if(event.keyCode==13){
event.returnValue = false;
ele.value+="{{enter}}"
return false;
}
}
</script>
</head>
<body>
<textarea rows="3" cols="40" id="te" onkeypress="back(this,event);"></textarea>
</body>
</html>
- 以下代码中end字符串什么时候输出
var t=true;
setTimeout(function(){
console.log(123);
t=false;
},1000);
while(t){}
console.log(‘end’);
永远不输出
- specify(‘hello,world’)//=>’h,e,l,l,o,w,o,r,l,d’实现specify函数
function specify(str){
var tempArray = Array.prototype.filter.call(str,function(value,index,array){
return value >= 'A' && value <= 'z' && value != "_";
});
return tempArray.join(",");
}
console.log(specify("hedd____df*(%$#a !!!))))))llo,[email protected]@@r ld")); //h,e,l,l,o,W,o,r,l,d
- 简述readyonly与disabled的区别
ReadOnly和Disabled的作用是使用户不能够更改表单域中的内容.
但是二者还是有着一些区别的:
1、Readonly只针对input(text/password)和textarea有效,而disabled对于所有的表单元素有效,包括select,radio,checkbox,button等。
2、在表单元素使用了disabled后,我们将表单以POST或者GET的方式提交的话,这个元素的值不会被传递出去,而readonly会将该值传递出去
请尽可能详尽的解释ajax的工作原理
Ajax的工作原理相当于在用户和服务器之间加了—个中间层,使用户操作与服务器响应异步化。这样把以前的一些服务器负担的工作转嫁到客户端,利于客户端闲置的处理能力来处理,减轻服务器和带宽的负担,从而达到节约ISP的空间及带宽租用成本的目的。
简单来说通过XmlHttpRequest对象来向服务器发异步请求,从服务器获得数据,然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。要清楚这个过程和原理,我们必须对 XMLHttpRequest有所了解。
- 为什么扩展javascript内置对象不是好的做法?
因为你不知道哪一天浏览器或javascript本身就会实现这个方法,而且和你扩展的实现有不一致的表现。到时候你的javascript代码可能已经在无数个页面中执行了数年,而浏览器的实现导致所有使用扩展原型的代码都崩溃了。。。
- 有下面这样一段HTML结构,使用css实现这样的效果:
左边容器无论宽度如何变动,右边容器都能自适应填满父容器剩余的宽度。
<div class=”warp”>
<div class=”left”></div>
<div class=”right”></div>
</div>
90.下面这段代码想要循环输出结果01234,请问输出结果是否正确,如果不正确,请说明为什么,并修改循环内的代码使其输出正确结果
for(var i=0;i<5;++i){
setTimeout(function(){
console.log(i+’’);
},100*i);
}
- 关于IE的window对象表述正确的有:(ACD)
A. window.opener属性本身就是指向window对象
B. window.reload()方法可以用来刷新当前页面 应该是location.reload或者window.location.reload
C. window.location=”a.html”和window.location.href=”a.html”的作用都是把当前页面替换成a.html页面
D. 定义了全局变量g;可以用window.g的方式来存取该变量
- 下面正确的是 A
A: 跨域问题能通过JsonP方案解决
B:不同子域名间仅能通过修改window.name解决跨域 还可以通过script标签src jsonp等h5 Java split等
C:只有在IE中可通过iframe嵌套跨域
D:MediaQuery属性是进行视频格式检测的属性是做响应式的
93.错误的是 c
A: Ajax本质是XMLHttpRequest
B: 块元素实际占用的宽度与它的width、border、padding属性有关,与background无关
C: position属性absolute、fixed、—relative—会使文档脱标
D: float属性left也会使div脱标
答案C:relative不会脱离文档流
- 三种弹窗的单词以及三种弹窗的功能
1.alert
//弹出对话框并输出一段提示信息
function ale() {
//弹出一个对话框
alert("提示信息!");
}
2.confirm
//弹出一个询问框,有确定和取消按钮
function firm() {
//利用对话框返回的值 (true 或者 false)
if (confirm("你确定提交吗?")) {
alert("点击了确定");
}
else {
alert("点击了取消");
}
}
3.prompt
//弹出一个输入框,输入一段文字,可以提交
function prom() {
var name = prompt("请输入您的名字", ""); //将输入的内容赋给变量 name ,
//这里需要注意的是,prompt有两个参数,前面是提示的话,后面是当对话框出来后,在对话框里的默认值
if (name)//如果返回的有内容
{
alert("欢迎您:" + name)
}
}
- 只允许使用 + - * / 和 Math.* ,求一个函数 y = f(x, a, b);当x > 100 时返回 a 的值,否则返回 b 的值,不能使用 if else 等条件语句,也不能使用|,?:,数组。
function f(x, a, b) {
var temp = Math.ceil(Math.min(Math.max(x - 100, 0), 1));
return a * temp + b * (1 - temp);
}
console.log(f(-10, 1, 2));
- JavaScriptalert(0.4*0.2);结果是多少?和你预期的一样吗?如果不一样该如何处理?
有误差,应该比准确结果偏大。 一般我会将小数变为整数来处理。当前之前遇到这个问题时也上网查询发现有人用try catch return写了一个函数,当然原理也是一致先转为整数再计算。
- jQuery框架中$.ajax()的常用参数有哪些?写一个post请求并带有发送数据和返回数据的样例
async是否异步
url请求地址
contentType发送信息至服务器时内容编码类型
data发送到服务器的数据
dataType预期服务器返回的数据类型
type请求类型
success请求成功回调函数
error请求失败回调函数
$.ajax({
url: "/jquery/test1.txt",
type: 'post',
data: {
id: 1
},
success: function(data) {
alert(data);
}
}
- 闭包:下面这个ul,如何点击每一列的时候alert其index?
<ul id="test">
<li>这是第一条</li>
<li>这是第二条</li>
<li>这是第三条</li>
</ul>
//js
window.onload = function() {
var lis = document.getElementById('test').children;
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = (function(i) {
return function() {
alert(i)
};
})(i);
};
}
- 列出3条以上ff和IE的脚本兼容问题
(1) window.event:
表示当前的事件对象,IE有这个对象,FF没有,FF通过给事件处理函数传递事件对象
(2) 获取事件源
IE用srcElement获取事件源,而FF用target获取事件源
(3) 添加,去除事件
IE:element.attachEvent(“onclick”, function) element.detachEvent(“onclick”, function)
FF:element.addEventListener(“click”, function, true) element.removeEventListener(“click”, function, true)
(4) 获取标签的自定义属性
IE:div1.value或div1[“value”]
FF:可用div1.getAttribute(“value”)
- 写一个函数可以计算 sum(5,0,-5);输出0; sum(1,2,3,4);输出10;
function sum() {
var result = 0;
var arr = arguments;
for (var i = 0; i < arr.length; i++) {
var num = arguments[i];
if (typeof num=='number') {
result += num;
};
};
return result;
}
101.《正则》写出正确的正则表达式匹配固话号,区号3-4位,第一位为0,中横线,7-8位数字,中横线,3-4位分机号格式的固话号
^[0]\d{2,3}-\d{7,8}-\d{3,4}$
102.《算法》 一下A,B可任选一题作答,两题全答加分
A:农场买了一只羊,第一年是小羊,第二年底生一只,第三年不生,第四年底再生一只,第五年死掉。
B:写出代码对下列数组去重并从大到小排列{5,2,3,6,8,6,5,4,7,1,9}
function fn(arr){
for (var i = 0; i < arr.length-1; i++) {
for (var j = 0; j < arr.length-1-i; j++) {
if(arr[j]<arr[j+1]){
var temp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
for (i = 0; i < arr.length; i++) {
var c=arr[i];
for (var s = i+1; s < arr.length; s++) {
if(arr[s]==c){
//debugger;
arr.splice(s,1);
s--;
}
}
}
return arr;
}
console.log(fn([5,2,3,6,8,6,5,4,7,1,9]).toString());
- 请写出一个程序,在页面加载完成后动态创建一个form表单,并在里面添加一个input对象并给它任意赋值后义post方式提交到:http://127.0.0.1/save.php
window.onload=function(){
var form=document.createElement("form");
form.setAttribute("method", "post");
form.setAttribute("action", "http://127.0.0.1/save.php");
var input=document.createElement("input");
form.appendChild(input);
document.body.appendChild(form);
input.value="cxc";
form.submit();//提交表单
}
- 用JavaScript实现冒泡排序。数据为23、45、18、37、92、13、24
//升序算法
function sort(arr){
for (var i = 0; i <arr.length; i++) {
for (var j = 0; j <arr.length-i; j++) {
if(arr[j]>arr[j+1]){
var c=arr[j];//交换两个变量的位置
arr[j]=arr[j+1];
arr[j+1]=c;
}
};
};
return arr.toString();
}
console.log(sort([23,45,18,37,92,13,24]));
- 下列JavaScript代码执行后,依次alert的结果是
(function test(){
var a=b=5;
alert(typeof a);
alert(typeof b);
})();
alert(typeof a);
alert(typeof b);
答案:number
number
undefined
number
- 下列JavaScript代码执行后,iNum的值是
var iNum = 0;
for(var i = 1; i< 10; i++){
if(i % 5 == 0){
continue;
}
iNum++;
}
答案:8
- 输出结果是多少?
1) var a;
var b = a * 0;
if (b == b) {
console.log(b * 2 + "2" - 0 + 4);
} else {
console.log(!b * 2 + "2" - 0 + 4);
}
答案:26
<script>
var a = 1;
</script>
<script>
var a;
var b = a * 0;
if (b == b) {
console.log(b * 2 + "2" - 0 + 4);
} else {
console.log(!b * 2 + "2" - 0 + 4);
}
</script>
答案:6
3) var t = 10;
function test(t){
var t = t++;
}test(t);
console.log(t);
答案:10
4) var t = 10;
function test(test){
var t = test++;
}test(t);
console.log(t);
答案:10
6) var t = 10;
function test(test){
t = test++;
}test(t);
console.log(t);
答案:10
7) var t = 10;
function test(test){
t = t + test;
console.log(t);
var t = 3;
}test(t);
console.log(t);
答案:NaN 10
8) var a;
var b = a / 0;
if (b == b) {
console.log(b * 2 + "2" - 0 + 4);
} else {
console.log(!b * 2 + "2" - 0 + 4);
}
答案:26
9)<script>
var a = 1;
</script>
<script>
var a;
var b = a / 0;
if (b == b) {
console.log(b * 2 + "2" + 4);
} else {
console.log(!b * 2 + "2" + 4);
}
</script>
答案:Infinity24
- 用程序实现找到html中id名相同的元素?
<body>
<form id='form1'>
<div id='div1'></div>
<div id='div2'></div>
<div id='div3'></div>
<div id='div4'></div>
<div id='div5'></div>
<div id='div3'>id名重复的元素</div>
</form>
</body>
var nodes=document.querySelectorAll("#form1>*");
for(var i=0,len=nodes.length;i<len;i++){
var attr=nodes[i].getAttribute("id");
var s=1;
for(var j=i+1;j<len;j++){
if(nodes[j].getAttribute("id")==attr){
s++;
alert("id为:"+attr+"的元素出现"+s+"次");
}
}
}
- 下列JavaScript代码执行后,运行的结果是
<button id='btn'>点击我</button>
var btn = document.getElementById('btn');
var handler = {
id: '_eventHandler',
exec: function(){
alert(this.id);
}
}
btn.addEventListener('click', handler.exec);
答案:”btn”
- 下列JavaScript代码执行后,依次alert的结果是
var obj = {proto: {a:1,b:2}};
function F(){};
F.prototype = obj.proto;
var f = new F();
obj.proto.c = 3;
obj.proto = {a:-1, b:-2};
alert(f.a);
alert(f.c);
delete F.prototype['a'];
alert(f.a);
alert(obj.proto.a);
答案:
1
3
undefined
-1
- 下列JavaScript代码执行后的效果是
<ul id='list'>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
var items = document.querySelectorAll('#list>li');
for(var i = 0;i < items.length; i++){
setTimeout(function(){
items[i].style.backgroundColor = '#fee';
}, 5);
}
答案:报错,因为i一直等于5,items[i]获取不到元素
- 下列JavaScript代码执行后的li元素的数量是
<ul>
<li>Item</li>
<li></li>
<li></li>
<li>Item</li>
<li>Item</li>
</ul>
var items = document.getElementsByTagName('li');
for(var i = 0; i< items.length; i++){
if(items[i].innerHTML == ''){
items[i].parentNode.removeChild(items[i]);
}
}
- 下列控制台都输出什么
第1题:
function setName(){
name="张三";
}
setName();
console.log(name);
答案:"张三"
第2题:
//考点:1、变量声明提升 2、变量搜索机制
var a=1;
function test(){
console.log(a);
var a=1;
}
test();
答案:undefined
第3题:
var b=2;
function test2(){
window.b=3;
console.log(b);
}
test2();
答案:3
第4题:
c=5;//声明一个全局变量c
function test3(){
window.c=3;
console.log(c); //答案:undefined,原因:由于此时的c是一个局部变量c,并且没有被赋值
var c;
console.log(window.c);//答案:3,原因:这里的c就是一个全局变量c
}
test3();
第5题:
var arr = [];
arr[0] = 'a';
arr[1] = 'b';
arr[10] = 'c';
alert(arr.length); //答案:11
console.log(arr[5]); //答案:undefined
第6题:
var a=1;
console.log(a++); //答案:1
console.log(++a); //答案:3
第7题:
console.log(null==undefined); //答案:true
console.log("1"==1); //答案:true,因为会将数字1先转换为字符串1
console.log("1"===1); //答案:false,因为数据类型不一致
第8题:
typeof 1; "number"
typeof "hello"; "string"
typeof /[0-9]/; "object"
typeof {}; "object"
typeof null; "object"
typeof undefined; "undefined"
typeof [1,2,3]; "object"
typeof function(){}; //"function"
第9题:
parseInt(3.14); //3
parseFloat("3asdf"); //3
parseInt("1.23abc456");
parseInt(true);//"true" NaN
第10题:
//考点:函数声明提前
function bar() {
return foo;
foo = 10;
function foo() {}
//var foo = 11;
}
alert(typeof bar());//"function"
第11题:
//考点:函数声明提前
var foo = 1;
function bar() {
foo = 10;
return;
function foo() {}
}
bar();
alert(foo);//答案:1
第12题:
console.log(a);//是一个函数
var a = 3;
function a(){}
console.log(a);////3
第13题:
//考点:对arguments的操作
function foo(a) {
arguments[0] = 2;
alert(a);//答案:2,因为:a、arguments是对实参的访问,b、通过arguments[i]可以修改指定实参的值
}
foo(1);
第14题:
function foo(a) {
alert(arguments.length);//答案:3,因为arguments是对实参的访问
}
foo(1, 2, 3);
第15题
bar();//报错
var foo = function bar(name) {
console.log("hello"+name);
console.log(bar);
};
//alert(typeof bar);
foo("world");//"hello"
console.log(bar);//undefined
console.log(foo.toString());
bar();//报错
第16题:
function test(){
console.log("test函数");
}
setTimeout(function(){
console.log("定时器回调函数");
}, 0)
test();
结果:
test函数
定时器回调函数
114.Ajax 是什么? 如何创建一个Ajax?
Ajax并不算是一种新的技术,全称是asychronous javascript and xml,可以说是已有技术的组合,主要用来实现客户端与服务器端的异步通信效果,实现页面的局部刷新,早期的浏览器并不能原生支持ajax,可以使用隐藏帧(iframe)方式变相实现异步效果,后来的浏览器提供了对ajax的原生支持
使用ajax原生方式发送请求主要通过XMLHttpRequest(标准浏览器)、ActiveXObject(IE浏览器)对象实现异步通信效果
基本步骤:
var xhr =null;//创建对象
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open(“方式”,”地址”,”标志位”);//初始化请求
xhr.setRequestHeader(“”,””);//设置http头信息
xhr.onreadystatechange =function(){}//指定回调函数
xhr.send();//发送请求
js框架(jQuery/EXTJS等)提供的ajax API对原生的ajax进行了封装,熟悉了基础理论,再学习别的框架就会得心应手,好多都是换汤不换药的内容
下的服务器负载。
- 一个页面从输入 URL 到页面加载显示完成,这个过程中都发生了什么?
分为4个步骤:
- 当发送一个 URL 请求时,不管这个 URL 是 Web 页面的 URL 还是 Web 页面上每个资源的 URL,浏览器都会开启一个线程来处理这个请求,同时在远程 DNS 服务器上启动一个 DNS 查询。这能使浏览器获得请求对应的 IP 地址。
- 浏览器与远程 Web 服务器通过 TCP 三次握手协商来建立一个 TCP/IP 连接。该握手包括一个同步报文,一个同步-应答报文和一个应答报文,这三个报文在 浏览器和服务器之间传递。该握手首先由客户端尝试建立起通信,而后服务器应答并接受客户端的请求,最后由客户端发出该请求已经被接受的报文。
- 一旦 TCP/IP 连接建立,浏览器会通过该连接向远程服务器发送 HTTP 的 GET 请求。远程服务器找到资源并使用 HTTP 响应返回该资源,值为 200 的 HTTP 响应状态表示一个正确的响应。
- 此时,Web 服务器提供资源服务,客户端开始下载资源。
116.请说出三种减低页面加载时间的方法
1、压缩css、js文件
2、合并js、css文件,减少http请求
3、外部js、css文件放在最底下
4、减少dom操作,尽可能用变量替代不必要的dom操作
117.HTTP状态码都有那些。
200 OK //客户端请求成功
400 Bad Request //客户端请求有语法错误,不能被服务器所理解
403 Forbidden //服务器收到请求,但是拒绝提供服务
404 Not Found //请求资源不存在,输入了错误的URL
500 Internal Server Error //服务器发生不可预期的错误
503 Server Unavailable //服务器当前不能处理客户端的请求,一段时间后可能恢复正常
- 实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制
考察点1:对于基本数据类型和引用数据类型在内存中存放的是值还是指针这一区别是否清楚
考察点2:是否知道如何判断一个变量是什么类型的
考察点3:递归算法的设计
// 方法一:
Object.prototype.clone = function(){
var o = this.constructor === Array ? [] : {};
for(var e in this){
o[e] = typeof this[e] === "object" ? this[e].clone() : this[e];
}
return o;
}
//方法二:
/**
* 克隆一个对象
* @param Obj
* @returns
*/
function clone(Obj) {
var buf;
if (Obj instanceof Array) {
buf = [];//创建一个空的数组
var i = Obj.length;
while (i--) {
buf[i] = clone(Obj[i]);
}
return buf;
}else if (Obj instanceof Object){
buf = {};//创建一个空对象
for (var k in Obj) { //为这个对象添加新的属性
buf[k] = clone(Obj[k]);
}
return buf;
}else{ //普通变量直接赋值
return Obj;
}
}
- 如何消除一个数组里面重复的元素?
var arr=[1,2,3,3,4,4,5,5,6,1,9,3,25,4];
function deRepeat(){
var newArr=[];
var obj={};
var index=0;
var l=arr.length;
for(var i=0;i<l;i++){
if(obj[arr[i]]==undefined)
{
obj[arr[i]]=1;
newArr[index++]=arr[i];
}
else if(obj[arr[i]]==1)
continue;
}
return newArr;
}
var newArr2=deRepeat(arr);
alert(newArr2); //输出1,2,3,4,5,6,9,25
- 小贤是一条可爱的小狗(Dog),它的叫声很好听(wow),每次看到主人的时候就会乖乖叫一声(yelp)。从这段描述可以得到以下对象:
function Dog() {
this.wow = function() {
alert(’Wow’);
}
this.yelp = function() {
this.wow();
}
}
小芒和小贤一样,原来也是一条可爱的小狗,可是突然有一天疯了(MadDog),一看到人就会每隔半秒叫一声(wow)地不停叫唤(yelp)。请根据描述,按示例的形式用代码来实。(继承,原型,setInterval)
function MadDog() {
this.yelp = function() {
var self = this;
setInterval(function() {
self.wow();
}, 500);
}
}
MadDog.prototype = new Dog();
//for test
var dog = new Dog();
dog.yelp();
var madDog = new MadDog();
madDog.yelp();
- 定义一个log方法,让它可以代理console.log的方法。
可行的方法一:
function log(msg) {
console.log(msg);
}
log("hello world!") // hello world!
如果要传入多个参数呢?显然上面的方法不能满足要求,所以更好的方法是:
function log(){
console.log.apply(console, arguments);
};
到此,追问apply和call方法的异同。
对于apply和call两者在作用上是相同的,即是调用一个对象的一个方法,以另一个对象替换当前对象。将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
但两者在参数上有区别的。对于第一个参数意义都一样,但对第二个参数: apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。 如 func.call(func1,var1,var2,var3)对应的apply写法为:func.apply(func1,[var1,var2,var3]) 。
- 对作用域上下文和this的理解,看下列代码:
var User = {
count: 1,
getCount: function() {
return this.count;
}
};
console.log(User.getCount()); // what?
var func = User.getCount;
console.log(func()); // what?
问两处console输出什么?为什么?
答案是1和undefined。
func是在winodw的上下文中被执行的,所以会访问不到count属性。
继续追问,那么如何确保Uesr总是能访问到func的上下文,即正确返回1。正确的方法是使用Function.prototype.bind。兼容各个浏览器完整代码如下:
Function.prototype.bind = Function.prototype.bind || function(context){
var self = this;
return function(){
return self.apply(context, arguments);
};
}
var func = User.getCount.bind(User);
console.log(func());
- 原生JS的window.onload与Jquery的
$(document).ready(function(){})有什么不同?如何用原生JS实现Jq的ready方法?
window.onload()方法是必须等到页面内包括图片的所有元素加载完毕后才能执行。
$(document).ready()是DOM结构绘制完毕后就执行,不必等到加载完毕。
/*
* 传递函数给whenReady()
* 当文档解析完毕且为操作准备就绪时,函数作为document的方法调用
*/
var whenReady = (function() { //这个函数返回whenReady()函数
var funcs = []; //当获得事件时,要运行的函数
var ready = false; //当触发事件处理程序时,切换为true
//当文档就绪时,调用事件处理程序
function handler(e) {
if(ready) return; //确保事件处理程序只完整运行一次
//如果发生onreadystatechange事件,但其状态不是complete的话,那么文档尚未准备好
if(e.type === 'onreadystatechange' && document.readyState !== 'complete') {
return;
}
//运行所有注册函数
//注意每次都要计算funcs.length
//以防这些函数的调用可能会导致注册更多的函数
for(var i=0; i<funcs.length; i++) {
funcs[i].call(document);
}
//事件处理函数完整执行,切换ready状态, 并移除所有函数
ready = true;
funcs = null;
}
//为接收到的任何事件注册处理程序
if(document.addEventListener) {
document.addEventListener('DOMContentLoaded', handler, false);
document.addEventListener('readystatechange', handler, false); //IE9+
window.addEventListener('load', handler, false);
}else if(document.attachEvent) {
document.attachEvent('onreadystatechange', handler);
window.attachEvent('onload', handler);
}
//返回whenReady()函数
return function whenReady(fn) {
if(ready) { fn.call(document); }
else { funcs.push(fn); }
}
})();
如果上述代码十分难懂,下面这个简化版:
function ready(fn){
if(document.addEventListener) {//标准浏览器
document.addEventListener('DOMContentLoaded', function() {
//注销事件, 避免反复触发
document.removeEventListener('DOMContentLoaded',arguments.callee, false);
fn();//执行函数
}, false);
}else if(document.attachEvent) {//IE
document.attachEvent('onreadystatechange', function() {
if(document.readyState == 'complete') {
document.detachEvent('onreadystatechange', arguments.callee);
fn();//函数执行
}
});
}
};
将循环控制量保存到局部变量
顺序无关的遍历时,用 while 替代 for
将条件分支,按可能性顺序从高到低排列
在同一条件子的多( >2 )条件分支时,使用 switch 优于 if
使用三目运算符替代条件分支
需要不断执行的时候,优先考虑使用 setInterval
- javascript对象的几种创建方式?
- 工厂模式
- 构造函数模式
- 原型模式
- 混合构造函数和原型模式
- 动态原型模式
- 寄生构造函数模式
- 稳妥构造函数模式
- javascript继承的 6 种方法?
- 原型链继承
- 借用构造函数继承
- 组合继承(原型+借用构造)
- 原型式继承
- 寄生式继承
- 寄生组合式继承
- eval是做什么的?
- 它的功能是把对应的字符串解析成JS代码并运行
- 应该避免使用eval,不安全,非常耗性能(2次,一次解析成js语句,一次执行)
- 关于javascript中apply()和call()方法的区别?
相同点:两个方法产生的作用是完全一样的
不同点:方法传递的参数不同
Object.call(this,obj1,obj2,obj3)
Object.apply(this,arguments)
apply()接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。
call()方法第一个参数与apply()方法相同,但传递给函数的参数必须列举出来。
- JavaScript原型,原型链 ? 有什么特点?
- 原型对象也是普通的对象,是对象一个自带隐式的 proto 属性,原型也有可能有自己的原型,如果一个原型对象的原型不为null的话,我们就称之为原型链。
- 原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链。
- JavaScript的数据对象有那些属性值?
writable:这个属性的值是否可以改。
configurable:这个属性的配置是否可以删除,修改。
enumerable:这个属性是否能在for…in循环中遍历出来或在Object.keys中列举出来。
value:属性值。
- 当我们需要一个属性的时,Javascript引擎会先看当前对象中是否有这个属性, 如果没有的话,就会查找他的Prototype对象是否有这个属性。
function clone(proto) {
function Dummy() { }
Dummy.prototype = proto;
Dummy.prototype.constructor = Dummy;
return new Dummy(); //等价于Object.create(Person);
}
function object(old) {
function F() {};
F.prototype = old;
return new F();
}
var newObj = object(oldObject);- 写一个通用的事件侦听器函数
// event(事件)工具集,来源:https://github.com/markyun
markyun.Event = {
// 页面加载完成后
readyEvent : function(fn) {
if (fn==null) {
fn=document;
}
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = fn;
} else {
window.onload = function() {
oldonload();
fn();
};
}
},
// 视能力分别使用dom0||dom2||IE方式 来绑定事件
// 参数: 操作的元素,事件名称 ,事件处理程序
addEvent : function(element, type, handler) {
if (element.addEventListener) {
//事件类型、需要执行的函数、是否捕捉
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent('on' + type, function() {
handler.call(element);
});
} else {
element['on' + type] = handler;
}
},
// 移除事件
removeEvent : function(element, type, handler) {
if (element.removeEnentListener) {
element.removeEnentListener(type, handler, false);
} else if (element.datachEvent) {
element.detachEvent('on' + type, handler);
} else {
element['on' + type] = null;
}
},
// 阻止事件 (主要是事件冒泡,因为IE不支持事件捕获)
stopPropagation : function(ev) {
if (ev.stopPropagation) {
ev.stopPropagation();
} else {
ev.cancelBubble = true;
}
},
// 取消事件的默认行为
preventDefault : function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
// 获取事件目标
getTarget : function(event) {
return event.target || event.srcElement;
},
// 获取event对象的引用,取到事件的所有信息,确保随时能使用event;
getEvent : function(e) {
var ev = e || window.event;
if (!ev) {
var c = this.getEvent.caller;
while (c) {
ev = c.arguments[0];
if (ev && Event == ev.constructor) {
break;
}
c = c.caller;
}
}
return ev;
}
};
- new操作符具体干了什么呢?
- 创建一个空对象,并且 this 变量引用该对象,同时还继承了该函数的原型。
- 属性和方法被加入到 this 引用的对象中。
- 新创建的对象由 this 所引用,并且最后隐式的返回 this 。
var obj = {};
obj.proto = Base.prototype;
Base.call(obj);
- 前端开发的优化问题(看雅虎14条性能优化原则)。
(1) 减少http请求次数:CSS Sprites, JS、CSS源码压缩、图片大小控制合适;网页Gzip,CDN托管,data缓存 ,图片服务器。
(2) 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数
(3) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能。
(4) 当需要设置的样式很多时设置className而不是直接操作style。
(5) 少用全局变量、缓存DOM节点查找的结果。减少IO读取操作。
(6) 避免使用CSS Expression(css表达式)又称Dynamic properties(动态属性)。
(7) 图片预加载,将样式表放在顶部,将脚本放在底部 加上时间戳。
(8) 避免在页面的主体布局中使用table,table要等其中的内容完全下载之后才会显示出来,显示比div+css布局慢。