【前端拾遗】笔试题目一
function Person(name) {
this.name = name;
}
Person.prototype = {
getName : function() {
return this.name;
}
}
function Student(name, id) {
Person.call(this, name)
this.id = id;
}
//接下来的一行,我们提供了有三种写法:
//第一种:Student.prototype = Person.prototype;
//第二种:Student.prototype = new Person();
//第三种:Student.prototype = Object.create(Person.prototype);
Student.prototype.getId = function() {
return this.id;
}
//请问:
//1.请简述代码中注释处的三种写法的每一种,是否正确,是否完美.如果都不够完美,那你应该如何写.
//2.除了注释处,代码的其他部分还有值得优化的地方么.
第一种写法不正确,将person的原型赋值给了student的原型,没有实现继承。
第二种写法是组合继承的写法,通过原型链在原型上定义方法实现了函数复用,又通过借调构造函数保证每个实例都有自己的属性。但是缺点就是无论什么情况下都会调用两次person的构造函数,第一次调用是new一个person的实例然后赋值给student的原型,第二次是在调用student的构造函数时会又一次调用它。
第三种写法是通过调用Object.create()实现了原型式继承,但是也有缺点就是一旦person的构造函数中有引用类型的属性,通过继承,student的原型中就有了一个引用类型的属性,这个属性会被所有student的实例共享,而这就是我们应该避免的。
最有效和优美的写法应该如下:
function object(o){
function F(){}
F.prototype=o;
return new F();
}
function inheritPrototype(student,person){
var prototype=object(person.prototype);
prototype.constructor=student;
student.prototype=prototype;
}
position的四个属性值:
- relative
- absolute
- fixed
- static
2. absolute
这个属性总是有人给出误导。说当position属性设为absolute后,总是按照浏览器窗口来进行定位的,这其实是错误的。实际上,这是fixed属性的特点。
当sub1的position设置为absolute后,其到底以谁为对象进行偏移呢?这里分为两种情况:
(1)当sub1的父对象(或曾祖父,只要是父级对象)parent也设置了position属性,且position的属性值为absolute或者relative时,也就是说,不是默认值的情况,此时sub1按照这个parent来进行定位。
注意,对象虽然确定好了,但有些细节需要您的注意,那就是我们到底以parent的哪个定位点来进行定位呢?如果parent设定了margin,border,padding等属性,那么这个定位点将忽略padding,将会从padding开始的地方(即只从padding的左上角开始)进行定位,这与我们会想当然的以为会以margin的左上端开始定位的想法是不同的。接下来的问题是,sub2的位置到哪里去了呢?由于当position设置为absolute后,会导致sub1溢出正常的文档流,就像它不属于 parent一样,它漂浮了起来,在DreamWeaver中把它称为“层”,其实意思是一样的。此时sub2将获得sub1的位置,它的文档流不再基于 sub1,而是直接从parent开始。
(2)如果sub1不存在一个有着position属性的父对象,那么那就会以body为定位对象,按照浏览器的窗口进行定位,这个比较容易理解。
3. fixed
fixed是特殊的absolute,即fixed总是以body为定位对象的,按照浏览器的窗口进行定位。
4. static
position的默认值,一般不设置position属性时,会按照正常的文档流进行排列。
三、apply和call的用法和区别
两者的作用都是将函数绑定倒另外一个对象上面去,两者仅仅在定义参数方式有所区别。对于第一个参数意义都一样,但对第二个参数:
apply传入的是一个参数数组,也就是将多个参数组合成为一个数组传入,而call则作为call的参数传入(从第二个参数开始)。
四、经典布局
用css、html编写一个两列布局的网页,要求右侧宽度为200px,左侧自动扩展。
我主要的想法是右侧绝对定位,左框右边距200px,正好空出了右侧的位置。
我写的CSS如下:
#right{
position:absolute;
right:0;
width:200px;
}
#left{
marin-right:200px;
}
另一种方法(试验有效):
#right{
float:right;
width:200px;
}
#left{
marin-right:200px;
}
HTML代码中#right必须写在#left前面
<body>
<div id=”right”>…</div>
<div id=”left”>…</div>
</body>
五、实时显示当前时间,格式为"年-月-日 时:分:秒"(javascript)
Number.prototype.format = function(){
return this < 10 ? ("0" + this) : this;
}
setInterval(function(){
var t = new Date(),
year = t.getFullYear(),
month = (t.getMonth()+1).format(),
day = t.getDate().format(),
hour = t.getHours().format(),
minute = t.getMinutes().format(),
second = t.getSeconds().format(),
str = year + "-" + month + "-" + day + " " + hour + ":" + minute + ":" + second;
document.body.innerHTML = str;
},1000);
注意事项:
1. getMonth()所取得的值需要+1后才可使用。
2. 为了显示规范,因为将单个字符前面加上0。(即上面format()函数的作用)。
六、块级元素和行内元素的区别
块级元素有:<h1>, <p>,<header>,<blockquote>, <div>,<code>,<pre>,<form>
行内元素有:<em>,<a>,<acronym>,<dt>, <input>, <strong>
块级元素和行内元素的区别有如下两点:第一:块级元素总是在新行上开始,占据一行,行内元素则和其他元素都在同一行上。第二:行内元素(除了少数几个如input和img等)不可以控制宽和高,除非将它转变成为块级元素,它的宽和高,是随标签里的内容而变化。块级元素可以用样式控制其高、宽的值。
七、正则表达式
1、验证email
var myReg = /^[_a-z0-9]+@([_a-z0-9]+.)+[a-z0-9]{2,3}$/;
if(myReg.test(strEmail)) return true;
2、判断字符串是否是这样组成的,第一个必须是字母,后面可以是字母、数字、下划线,总长度为5-20
var reg = /^[a-zA-Z][a-zA-Z_0-9]{4,19}$/;
reg.test("a1a__a1a__a1a__a1a__");
function test() {
a = 100;
alert(a); //100
alert(this.a); //10
var a;
alert(a); //100
}
var script=document.creatElement("script");
script.type="text/javascript";
if(script.readyState){
callback();
}
}
}else{
script.onload=function(){
callback();
}
}
script.src=url;
document.getElementsByName("head")[0].appendChild(script);
}
十一、规避javascript多人开发函数重名问题
(1) 可以开发前规定命名规范,根据不同开发人员开发的功能在函数前加前缀
(2) 将每个开发人员的函数封装到类中,调用的时候就调用类的函数,即使函数重名只要类名不重复就ok
十二、使用javascript深度克隆一个对象
function cloneObject(obj){
var o = obj.constructor === Array ? [] : {};
for(var i in obj){
if(obj.hasOwnProperty(i)){
o[i] = typeof obj[i] === "object" ? cloneObject(obj[i]) : obj[i];
}
}
return o;
}
//将字符串的字符保存在一个hash table中,key是字符,value是这个字符出现的次数
var str = "abcdefgaddda";
var obj = {};
for (var i = 0, l = str.length; i < l; i++) {
var key = str[i];
if (!obj[key]) {
obj[key] = 1;
}
else {
obj[key]++;
}
}
/*遍历这个hash table,获取value最大的key和value*/
var max = -1;
var max_key = "";
var key;
for (key in obj) {
if (max < obj[key]) {
max = obj[key];
max_key = key;
}
}
function parseQueryString(url){
var params = {};
var arr = url.split("?");
if (arr.length <= 1) return params;
arr = arr[1].split("&");
for(var i=0,l=arr.length; i<l;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);
if (/efg/.test(str)) {
var substr = str.substr(str.indexOf("efg"), 3);
alert(substr);
}
if(this.length<2) return [this[0]]||[];
var arr=[];
for(var i=0;i<this.length;i++)
{
arr.push(this.splice(i--,1));
for(var j=0;j<this.length;j++)
{
if(this[j]==arr[arr.length-1])
{
this.splice(j--,1);
}
}
}
return arr;
}
var arr=["abc",85,"abc",85,8,8,1,2,5,4,7,8];
alert(arr.strip());
第二种方法:
Array.prototype.unique = function(){
var ret = [];
var o = {};
var len = this.length;
for (var i=0; i<len;i++){
var v = this[i];
if (!o[v]){
o[v] = 1;
ret.push(v);
}
}
return ret;
}
var arr = [1 ,1 ,2, 3, 3, 2, 1];
(1)Var str = “hello world”;
(2)Var str2 = new String(“hello world”);
function IsString(str){
return (typeof str == "string" || str.constructor == String);
}
var str = "";
alert(IsString(1));
alert(IsString(str));
alert(IsString(new String(str)));
(1) 减少http请求次数:css spirit,data uri
(2) JS,CSS源码压缩
(3) 前端模板 JS+数据,减少由于HTML标签导致的带宽浪费,前端用变量保存AJAX请求结果,每次操作本地变量,不用请求,减少请求次数
(4) 用innerHTML代替DOM操作,减少DOM操作次数,优化javascript性能
(5) 用setTimeout来避免页面失去响应
(6) 用hash-table来优化查找
(7) 当需要设置的样式很多时设置className而不是直接操作style
(8) 少用全局变量
(9) 缓存DOM节点查找的结果
(10) 避免使用CSS Expression
(11) 图片预载
Ajax的优势
(1) 可搜索型
(2) 开放性
(3) 费用
(4) 易用性
(5) 易于开发
Flash的优势
(1) 多媒体处理
(2) 兼容性
(3) 矢量图形 比SVG,Canvas优势大很多
var len = str.length;
var bytes = len;
for(var i=0; i<len;i++){
if(str.charCodeAt(i) > 255){
bytes++;
}
return bytes;
}
}
(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”)
(5) document.getElementsByName()和document.all[name]
IE:document.getElementsByName()和document.all[name]均不能获取div元素
FF:可以
(6) input.type的属性
IE:input.type只读
FF:input.type可读写
(7) innerText textContent outerHTML
IE:支持innerText, outerHTML
FF:支持textContent
(8) 是否可用id代替HTML元素
IE:可以用id来代替HTML元素
FF:不可以