前端知识点
<meta>
标签
<meta name="keywords" content="HTML,ASP,PHP,SQL">
定义:元数据(metadata)是关于数据的信息,标签提供关于html文档的元数据,元数据不会显示在页面上,但对于机器是可读的。典型的情况是,meta元素被用于规定页面的描述,关键词,文档的作者、最后修改时间以及其他元数据。
用法:必属属性:content
,当有http-equiv
或者name
数学的时候,一定要有content属性对其进行说明。
可选属性:http-equiv
, name
, scheme
-
name
author
:定义页面作者
description
:定义web网页描述
keywords
:为搜索引擎设计,通知搜索引擎这个网页包含的信息是xxxx。
generator
:包含生成页面的软件的标识符
revised
:记录网页的最后修改时间 -
http-equiv 为名称/值对提供了名称。并指示服务器在发送实际的文档之前先在要传送个浏览器的MIME文档头部包含名称/值对。
content-type
:设置页面使用的字符集
expires
:设定网页的到期时间。
refresh
:自动刷新并指向新页面
set-cookie
:
更多属性值可以查看下这个链接:
http://www.divcss5.com/html/h50455.shtml
常用meta标签:
- charset 声明文档使用的字符编码,解决乱码
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- 百度禁止转码
<meta http-equiv="Cache-Control" content="no-siteapp" />
- viewport 移动端页面布局
<meta name="viewport" content="width=device-width,initial-scale=1.0">
content参数
width :数值/device-width
height:数值/device-width
initial-scale:初始缩放比例
maximum-scale:最大缩放比例
minimum-scale:最小缩放比例
user-scalable:是否允许用户缩放
HTML和HTML5
-
HTML5新增的元素:
-
新增的结构元素(section、article、aside、header、hgroup、footer、nav、figure)
-
新增的其他元素(video、audio、embed、mark、 progress、meter、time、ruby、rt、rp、wbr、canvas、command、details、datagrid、keygen、output、source、menu)
-
新增的input元素的类型(email、url、number、range、Date 、Search)
-
HTML5废弃的元素
能使用CSS代替的元素(basefont、big、center、font、s、tt、u)等等 不再使用frame框架
-
HTML5设置的文档声明
<!DOCTYPE html>
点透事件
问题的产生:
- box1和box2直接没有后代,继承关系,box1的z-index大于box2,即box1显示在box2浮层之上。
- box1元素发生touch,box1在touch事件后立即消失
- box2事件绑定click
用户触碰box1时,会先触发touchstart和click两个事件,touchstart优先级高。主要原因:click事件的触发有200~300ms的延时。box1.ontouchstart=function(e) { console.log('box1被摸了'); box1.style.display = 'none'; } box2.onclick = function() { console.log('box2被点了'); }
解决方法:preventDefault//阻止浏览器的默认行为
注:pc端没有点透事件,因为pc端鼠标点击无延迟。box.ontouchstart=function(event){ event.preventDefalut(); }
JavaScript的基本数据类型
js的基本数据类型有字符型、数值型、布尔值、null、undefined、symbol
symbol
symbol
主要作用:给变量提供唯一的标识,可以解决全局变量冲突的问题。
let s1=Symbol();
let s2=Symbol('another symbol')//Symbol实例的一个描述信息
每个Symbol实例都是唯一的。
使用一个共享的Symbol:
let gs1=Symbol.for('golbal_symbol_1');
let gs2=Symbol.for('global_symbol_1');
gs1===gs2
方法:使用Symbol.for()创建、获取Symbol
应用场景:使用Symbol定义类的私有属性/方法,替代常量,作为属性的key名。当使用Symbol实例作为属性key名时,无法使用Object.keys(obj)
、Object.getOwnPropertyNames(obj)
获取到,使用JSON.stringify()
将对象转换为JSON字符串时,Symbol属性也会被排除在输出内容之外。可以使用Obj.getOwnPropertySymbols(obj)
、Reflect.ownKeys(obj)
获取。
js中==
和===
区别
理解:当进行==
比较时,先检查两个操作数数据类型,如果相同,则进行===
比较,如果不同,则进行一次类型转换,转换为相同类型后进行比较。而===
比较时,如果类型不同,则直接返回false
- 转换规则
- 如果有一个操作数是布尔值,则在比较相等性之前将其转换为数值
- 如果有一个操作数是字符串,另一个操作数为数值,则比较相等性之前先将字符串转换为数值,
- 如果一个操作数是对象,另一个操作数不是,则调用对象的valueOf()方法,用得到的基本类型值按照前面的规则进行比较。
比较规则:
- null和undefined是相等的
- 要比较相等性之前,不能将null和undefined转换为其他任何值
- 如果有一个操作数是NaN,则相等操作符返回false,不相等返回true。即使两个操作数都是NaN,相等也是false。
- 如果两个操作值都是对象,则需要比较两者是否为同一个引用对象。
例子:
注:!可以将变量转换为Boolean类型,null,undefined,NaN以及空字符串取反都为true,其余为false。
[]==![]
->[]==false
->[]==0
->[].toString()==0
->' '==0
->0==0
->true;
{}==!{}
->{}==false
->{}==0
->({}).toString()==0
-> [object Object] == 0
->false
- toString()与valueOf()的区别:
toString()和valueOf()都是对象的方法。toString()方法返回反应这个对象的字符串。valueOf()方法如果存在任意原始值,就默认将对象转换为表示它的原始值;对象是复合值,而大多数对象无法真正表示为一个原始值,因此默认的valueOf()方法简单返回对象本身,而不是返回原始值。
1)undefined和null没有这两个方法
2)Object.prototype.toString()可以识别标准类型及内置对象类型,但不能识别自定义类型。
3)toString()可以区分内置函数和自定义函数function test(){ alert(1);//test } test.toString(); /*"function test(){ alert(1);//test }"*/ Function.toString(); //"function Function() { [native code] }" 内置函数 test.valueOf(); /*function test(){alert(1);//}*/ Function.valueOf(); //Function() { [native code] } 返回原函数 Function.valueOf().toString == Function.toString //true
js创建对象的几种方式
- 字面量模式创建
var person={ name:'hz', age:'12'; sex:'male' }
- 实例化一个Object对其添加属性和方法
工厂模式:var person=new Object(); person.name='hz';
function createPerson(name,age,sex){ var o=new Object(); o.name='hz'; o.sayname=function(){ } }
- 用函数模拟class创建实例
构造函数缺点:每个方法都要在每个实例上重新创建以便。person1,person2中的sayName()方法不是同一个Function的实例。因为JS中的函数是对象,因此每定义一个函数,也就是实例化一个对象。function Person(name,age,sex){ this.name=name; this.age=age; this.sex=sex; this.sayName=function(){ } } var person1=new Person('hz',21,'male'); var person2=new Person('dd',21,'name'); person1.sayName==person2.sayName //false;
function Person(name,age,sex){
this.name=name;
this.age=age;
this.sex=sex;
this.sayName=new Function();
} - 使用原型对象的方式,prototype关键字
function Person(){} Person.prototype.name='hx'; Person.prototype.sayName=function(){ } var person1=new Person(); var person2=new Person(); person1.sayName== person2.sayName;//true
- 组合使用构造函数模式和原型模式
js继承方式
-
原型链继承:将子构造函数的原型对象指向父构造函数的实例对象,那么子构造函数的实例对象可继承父类上的属性及方法。缺点是创建子类时不能向父类传参,并且父类原型上的所有引用类型(父类属性)可应用到所有实例对象上。
function Father(name,age){ this.name=name; this.age=age; } Father.prototype.getName=function(){ return this.name; } function Child(skill){ this.skill=skill; } Child.prototype=new Father('zhangsan',20); var child=new Child('dance'); console.log(child.getName())//zhangsan
-
构造函数继承:通过在子类中使用对父构造函数使用call方法来调用,优点:避免引用类型的属性被所有实例共享,也解决了不能传参的问题。缺点:方法在构造函数中定义了,每次创建实例时都要创建一遍方法。
function Father(name,age){ this.name=name; this.age=age; this.getName=function(){ return this.name; } this.getAge=function(){ return this.age; } } function Child(name,age,skill){ Father.call(this,name,age); this.skill=skill } var child=new Child('zhangsan',20,'dance'); console.log(child.getName())//zhangsan
-
组合继承:通过结合了原型链继承和构造函数继承
funtion Father(name,age){ this.name=name; this.age=age; } Father.prototype.money=function(){ console.log('100000'); } function Child(name,age,skill){ Father.call(this,name,age); this.skill=skill } Child.prototype=new Father(); Child.prototype.constructor=Child;//Child原型对象的构造函数 Child.prototype.exam=function(){ console.log(''); } var child=new Child('zhangsan',20,'dance'); console.log(child.money())
-
原型式继承:
function createObj(o){ function F(){}; F.prototype=o; return new F(); } var person={ name:'zhangsan', age:20 } var person1=createObj(person); var person2=createObj(person); person1.name='lisi'; console.log(person1.name,person2.name)
-
寄生式继承
function Father(name,age){ this.name=name; this.age=age; } function Child(name,age){ Father.call(this,name,age); } (function(){ var Super=function(){}; Super.prototype=Father.prototype; Child.prototype=new Super(); })(); Child.prototype.constructor=Child; var child=new Child('Tom',20); console.log(child.name);
prototype、proto、constructor解析
- 构造器constructor,原型prototype
每个对象有一个function Person(name) { this.name = name; } var person1 = new Person('xiaoming'); var person2 = new Person('xiaoli');
constructor
属性,指向这个对象所在的构造函数。每个对象都有个proto
属性指向创建它的构造函数的原型。person1.constructor==Person;//true; person1._proto_ == Person.prototype;
Person.prototype
是Person的原型“对象”,所以这个对象也有constructor
属性,同样指向Person。Person.prototype.constructor==Person;//Person原型对象的构造函数 Person._proto_=Function.prototype;Person构造函数的原型对象 Person.prototype._proto_==Object.prototype;//Person原型对象的构造函数原型
Person.prototype=> { constructor:f Person(), _proto_:Object }
-
JavaScript 原型,原型链?有什么特点?
在Javascript中我们使用构造函数创建了一个实例对象时,每个构造函数内部都有一个prototype属性,这个属性是一个对象,即原型对象。实例对象内部的proto属性指向构造函数的原型对象,并且该原型对象也可以看出其构造函数的实例,这个proto属性就是原型链。当我们要查找实例对象身上的某个属性及方法时,若该实例对象身上没有,可沿着proto属性一级一级向上找,直到Object.prototype.
特点:Javascript中时利用引用来进行传递的,当我们修改了某个原型的属性时,所有继承都会被修改。
闭包
函数内部创建的内部函数可以访问它们所在的外包函数中申明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含他们的外包函数之外被调用时,就会形成闭包。
- 写法
- 使用prototype属性定义
function Circle(r){ this.r=r; } Circle.PI=3.13159; Circle.prototype.area=function(){ return Circle.PI*this.r*this.r; } var c=new Circle(1.0); alert(c.area())
-
var Circle=new Object(); Circle.pi=3.1415; Circle.Area=fuction(r){ return this.pi*r*r; } alert(Circle.Area(1));
注:
- 不使用prototype属性定义的对象方法,是静态方法,只能直接用类名进行调用。另外,静态方法中无法使用this变量来调用对象其他属性
- 使用prototype属性定义的对象方法,是非静态方法,只有在实例化才能使用,其方法内部可以this来引用对象自身中的其他属性。
- 用途:
- 可以在函数外包调用闭包函数,在外包获取到函数内部的变量
- 将已经运行结束的函数上下文中的变量对象保存在内存中,通过闭包函数保存了对变量对象的引用,因此这个变量对象不会被回收.
严格模块
‘use strict’是ECMAScript 5 引入的一条指令。与普通语句的区别:
- 不包含任何语言的关键字
- 只能出现在脚本代码的开始或者函数体的开始、任何实体语句之前。
严格模式和非严格模式之间的区别:
- 禁止使用
with
语句 - 在严格模块中,所有变量都需要申明
- 在严格模式中,调用函数中的一个this值是undefined,在非严格模式中,调用的函数中的this值总是全局对象。
- 在严格模式中,当
delete
运算符后跟随非法的标识符(变量,函数,函数参数)时,将会抛出一个语法错误异常,在非严格中,delete
表达式什么都没做,并返回false
。 - 严格模式中,在一个对象直接量定义两个或多个同名属性将产生语法错误。
- 严格模式中,函数声明中存在两个或多个同名的参数将产生语法错误。
补充:delete语法:删除对象的一个属性
- 删除对象属性
- 不能删除变量
- 不能删除函数
- 不能删除原型链中的变量
- 可以删除数组变量
var arr=[1,2,3,4]; delete arr[0]; console.log(arr) //[empty,2,3,4]
This对象
this关键字:代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。
this关键字虽然会根据环境变化,但是它始终待代表的是调用当前函数的那个对象。JS中函数调用的模式:方法调用模式、函数调用模式、构造器调用模式、apply调用模式。
- 方法调用模式
当函数被保存为一个对象的属性时,它可成为这个对象的方法。当一个方法被调用时,this被绑定到这个对象上。如果调用表达式包含一个提取属性的动作(或[]),那么它被成为方法调用。
sayName函数作为对象obj的方法调用,所有函数体的this代表obj对象。var obj={ name:'kxy', sayName:function(){ console.log(this.name); } } obj.sayName();
- 函数调用模式
函数体中的this代表window对象,被绑定为全局对象。var name="ddd'; function sayName(){ console.log(this.name); }
- 构造函数模式
如果在一个函数前面加上new关键字来调用,那么就会创建一个连接到该函数的prototype成员的新对象,同时,this被绑定到这个新对象上。function Obj(){ this.name='kxy'; } var person=new Obj(); console.log(person.name);
apply
调用模式
所以的函数对象都有两个方法:apply和call。var person={ name:'kxy' } function sayName(){ console.log(this.name); } sayName();//this表示window sayName.apply(person);//this绑定到person对象 sayName.apply();//this表示window
注:apply()
和call()
语法:apply
和call
都可以继承另外一个对象的方法和属性。
Function.apply(obj,args);
obj
:这个对象将代替Function类中的this对象
args
:这个是数组,作为参数
function Person(name,age){
this.name=name;
this.age=age;
}
function Student(name,age,grade){
//Person.apply(this,arguments);//特点:this指代student对象,只接收2个参数,arguments为隐式类数组对象,用来接收传入的参数;
Person.call(this,name,age);//特点:this指代student对象,可以接收任意多个参数
this.grade=grade;
}
var student=new Student('zhangsan',22,'二年级');
-
什么情况用apply,什么情况用call
使用apply的情况:在给对象参数的情况下,如果参数的形式是数组的时候,
使用call的情况:如果Person的参数列表是(age,name)
,而Student的参数列表是(name,age,grade)
,则可以用call来实现。 -
call 的其他重要用法:call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
-
直接用A对象来替换B对象
-
直接用B对象来执行A对象的方法
function Class1() { this.name = "class1"; this.showNam = function() { alert(this.name); } } function Class2() { this.name = "class2"; } var c1 = new Class1(); var c2 = new Class2(); c1.showNam.call(c2);
把c1的方法放在c2上执行。
-
可以用call来实现继承
function Class1() { this.showTxt = function(txt) { alert(txt); } } function Class2() { Class1.call(this); } var c2 = new Class2(); c2.showTxt("cc");
Class1.call(this)
表示使用Class1对象代替this对象
JS有几种类型的值,
- 栈:原始数据类型(undefined,null,Boolean,number,String)
- 堆:引用数据类型(对象,数组,函数)
区别:
浏览器兼容
- css样式兼容性问题
- js语法
- dom标签表示形式
- 其他(hack)
样式兼容性(css)方面
- 使用通配符选择器*
- 添加浏览器前缀:ie:-ms,firefox:-moz;opera:-o;chrome:-webkit、
- ie9以下浏览器不能使用capacity,
使用:filter:alpha(opacity=50)ie6~ie8;
常见的兼容性问题
- 不同浏览器的标签默认的margin合padding不同
解决方案:css里的增加通配符*{margin:0;padding:0}; - IE6双边距问题:在IE6中设置了float,同时又设置了margin,就会出现边距问题
解决方案:设置display:inline - 图片默认有边距
解决方案:使用float为img布局 - 边距重叠问题;当相邻两个元素都设置了margin边距时i,margin取最大值,
解决方案:为了不让边重叠,可以给与子元素增加一个父级元素,并设置父级元素为overflow:hidden; - cursor:hand显示手型在safari上不支持
解决方案:统一使用cusor:pointer; - 两个块级元素,父元素设置为overflow:auto;子元素设置为position:relative,且高度大于父元素,在IE6和IE7会被隐藏而不是溢出。
解决方案:设置父级元素为position:relative。
Node.js
-
模块
-
模块的使用
hello.js
文件'use strict' var s='hello'; function greet(name){ console.log(name); } module.exports=greet;
使用hello模块中间的greet函数
'use strict' var greet=require('./hello'); var s='dd'; greet(s);
-
CommonJS规范
每个.js
文件都是一个模块,内部声明的变量名和函数名都互不冲突。 -
模块原理
Node首先准备一个对象module
:var module={ 'id':'hello', exports:{} }; var load=function(module){ function greet(name){ console.log("hello") } module.exports=greet; return module.exports; } var exported=load(module);//greet save(module,exported);
当使用require()获取module时,Node找到对应的module,把这个module的exports变量返回。
var greet=require('./hello');
-
module.exports 和exports
exports是module.exports的一个引用。
require引用模块后,返回的是module.exports而不是exports.
exports.xxx相对于导出对象是挂属性,该属性对调用模块直接可见,exports=相对月exports对象重新赋值,调用模块不能访问exports对象及其属性。console.log(module); //你会看到Module中的exports为空对象{} console.log(exports); //你会看到Module中的exports为空对象{} module.exports = { print : function(){console.log(12345)} } console.log(module); //你会看到Module中的exports对象有了print()方法 exports.name = '小白妹妹'; console.log(module); //你会看到Module中的exports对象不仅有了print()方法,还有了name属性
-
使用
module.exports={ foo:function(){return 'fpp'}; }
或者
module.exports=function(){return 'fpp}
或者
exports.foo=function(){return 'fpp'}
**使用exports需要添加新的键值,使用module.exports可以直接对对象赋值。
-
-
stream 仅在服务区端可用的模块。
特点:数据是有序的,必须依次读取或者依次写入。
主要学习来源:
https://www.nowcoder.com/discuss/412972?type=post&order=time&pos=&page=1&channel=1000&source_id=search_post&subType=2
廖雪峰官方网站