JavaScript 知识点及练习

一. 数据类型

值类型:Number,String,Boolean,undefined,null
引用类型:array,object,function

1、判断数据类型typeof

typeof可以返回6个结果:number、string、boolean、object、undefined、function

console.log(typeof(aaa));//"undefined"
console.log(typeof(typeof(aaa)));//string

console.log(typeof(undefined));//undefined
console.log(typeof(NaN));//number
console.log(typeof(null));//object

console.log(typeof(function(){}));//function
console.log(typeof([]));//object
console.log(typeof({}));//object

console.log(typeof(123));//number
console.log(typeof(new Number(123)));//object

var a='123abc';
console.log(typeof(+a));//number
console.log(typeof(!!a));//boolean
console.log(typeof(a+""));//string

console.log('11'+11);//1111
console.log(parseInt('123abc'));//123
var num = 123123.345789;
console.log(num.toFixed(3));//123123.346

2、数据类型的显示转换

console.log(Number(null));//0
console.log(Number('a'));//NaN
console.log(Number(undefined));//NaN
console.log(parseInt(true));//NaN

3、数据类型的隐示转换

 1.  isNaN
 2.  ++/--    +/-
 3.  +
 4.  */%
 5.  && || !
 6.  <     >    <=    >=
 7.  ==    !=
 其中1-5调用显式类型里面的Number();
     6-7调用显式类型的Boolean();
其中不发生类型转换的有:
===:绝对等于
!==:绝对不等于

4、特殊情况

NaN是非数,不等于任何。
在这里插入图片描述

练习题一

var str = false + 1 ;       
console.log(str);//1
var demo = false == 1;
console.log(demo);//false
if(typeof(a) && -true + (+undefined) + "" ){
    console.log('基础扎实');//基础扎实
}
if(11 + "11" * 2 == 33){
    console.log('基础扎实');//基础扎实
}
!!" " + !!"" - !!false||console.log('哈哈哈');//不打印

//" " 空格字符串,boolean值为true
//""  空串,boolean值为false

二. 函数

google新版本if里面不能定义函数,IE8可以

练习题一,形参、实参

function sum(a,b){//形参
	if(arguments.length>sum.length){
		console.log('实参多了');
	}
	else if(arguments.length<sum.length){
		console.log('形参多了');
	}
	else{
		console.log('相等');
	}
}
sum(1,2,3);//实参

练习题二

function b(x, y, a){
	arguments[2] = 10;//a=10
	console.log(a);
}
b(1,2,3);

1、立即执行函数

立即执行函数:函数执行过后立即被销毁
(function (){}());//W3C推荐
(function (){})();

针对初始化功能的函数,可以有参数。

var num = function (a,b){
    return a + b;
}(1,2);
 
(function abc(){
    var a = 123;
    var b = 234;
    console.log(a+b);
}())

只有表达式才能被执行符号执行,能被执行符号执行的表达式,函数名字会被自动忽略。

function test(){
    console.log("a");
}()    //会出现语法解析错误,因为括号前面是函数声明
 
(+ function test( ){
    console.log('a');
}())     //打印出a
// 阿里面试题
function test(a, b, c, d){
    console.log(a + b + c + d);
}(1, 2, 3, 4);
// 不报错也没有执行

2、递归

递归有两个重要的步骤:1、找规律; 2、找出口

典型示例:斐波那契额额数列:1 1 2 3 5 8
递归

3、arguments.callee指向函数自身引用

区别 func.caller

三、预编译

1、全局变量

①.imply global暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局对象所有

var a=b=3;
window.a==》没有
window.b==》有

②.一切声明的全局变量,全是window的属性
全局的var a=10;==》window.a=10;
window就是全局的域

全局执行期上下文:生成了一个GO对象
Global Object
GO === window

一旦经历了var的操作,所得出的属性(window),这种属性叫做不可配置的属性
不可配置的属性delete不掉

2、预编译

js运行三部曲:语法分析、预编译、解释执行

预编译发生在函数执行的前一刻

函数声明整体提升
变量 声明提升

3、预编译四部曲

1.创建AO对象(Activation Object)(执行期上下文) GO==window
2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
3.将实参值和形参统一
4.在函数体里面找函数声明,值赋予函数体
PS:先生成GO,再生成AO,如果AO、GO都有某个属性,优先取AO的

练习题一

function fn(a){
	console.log(a);
	
	var a = 123;
	console.log(a);
	
	function a(){}//函数声明
	console.log(a);
	
	var b = function(){}//函数表达式
	console.log(b);
	
	function d(){}
}
fn();

练习题二

function test(a,b){
	console.log(a);
	c=0;
	var c;
	a=3;
	b=2;
	console.log(b);
	function b(){}
	function d(){}
	console.log(b);
}
test(1);

第一步:
AO{
}
第二步:
AO{
	a: undefined,
	b: undefined,
	c: undefined
}
第三步:
AO{
	a: 1,
	b: undefined,
	c: undefined
}
第四步:
AO{
	a: 1,
	b: function b(){},
	c: undefined,
	d: function d(){}
}
//输出1 、 2、 2

四、作用域、作用域链

1、基础概念

  • [[scope]]:每个JavaScript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供JavaScript引擎存取,[[scope]]就是其中一个。
    [[scope]]指的就是我们所说的作用域,其中存储了执行期上下文的集合。
  • 作用域链:[[scope]] 中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们把这种链接叫做作用域链。
  • 运行期上下文:当函数执行时,会创建一个称为执行期上下文的内部对象(AO)。一个执行期上下文定义了一个函数执行的环境,函数每次执行时对应的执行环境都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生的执行上下文被销毁。
  • 查找变量:从作用域链的顶端依次向下查找。
function a(){
    function b(){
        function c(){
 
        }
        c();
    }
    b();
}
a();
 
 
a defined a.[[scope]] ----> 0 : GO          //a定义的时候产生GO对象
a doing   a.[[scope]] ----> 0 : aAO         //a执行的时候新产生AO对象
                            1 : GO
 
b defined b.[[scope]] ----> 0 : aAO         //子级b定义会继承父级a运行时产生的对象
                            1 : GO 
b doing   b.[[scope]] ----> 0 : bAO         //子级b新产生AO对象
                            1 : aAO 
                            2 : GO 
                              
c defined c.[[scope]] ----> 0 : bAO         //c定义时会继承b运行时产生的属性
                            1 : aAO 
                            2 : GO                        
c doing   c.[[scope]] ----> 0 : cAO         //c执行时同时又产生新的AO
                            1 : bAO 
                            2 : aAO 
                            3 : GO 

五、闭包

1、现象

当内部函数被保存到外部时,将会生成闭包,闭包会导致原有作用域链不释放,造成内存泄漏

2、触发情况

两个或多个函数互相嵌套,把里面的函数保存到外部,这样的情况一定会产生闭包。从外面还可以调用里面的函数。

3、作用

1.实现公有变量,eg:函数累加器
2.可以做缓存,存储结构,eg:eater
3.可以实现封装,属性私有化,eg:Person()
4.模块化开发,防止污染全局变量

练习题一

function a(){
	function b(){
		var bbb = 234;
		console.log(aaa);
	}
	var aaa = 123;
	return b;
}

var glob = 100;
var demo = a();
demo();

练习题二

function a1(){
	var num=100;
	function b(){
		num++;
		console.log(num);
	}
	return b;
}
var a111=a1();
a111();
a111();

练习题三

function test(){
	var arr = [];
	for(var i = 0 ; i < 10 ; i++){
		// 输出10个10
		arr[i] = function(){
			console.log(i+"、");
		}
		// 采用立即执行函数修改代码后,输出0~9
		/*(function (j){
			arr[j] = function(){
				console.log(j+"、");
			}
		}(i));*/
	}
	return arr;
}
var myArr = test();
for(var j = 0 ; j < myArr.length ; j++){
	myArr[j]();
}

练习题四,私有化变量

function Person(name,age,sex){
	var a=0;
	this.name=name;
	this.age=age;
	this.sex=sex;
	function sss(){
		a++;
		console.log(a);
	}
	this.say=sss;
}

var oPerson = new Person();
oPerson.say();//1
oPerson.say();//2
var oPerson1 = new Person();
oPerson1.say();//1

六、对象

1、对象的创建方法

  1. var obj = {},plainObject,对象字面量/对象直接量
  2. 构造函数
    1)系统自带的构造函数,new Object()
    2)自定义,大驼峰命名规则
  3. Object.create(原型, definedProperty特性);//可读不可写特性

2、构造函数的内部原理

  1. 在函数体最前面隐式的加上var this = {};
  2. 执行this.xxx=yyy;
  3. 隐示的返回this

七、包装类

原始值没有属性和方法

1、其一:String

var str = 'abcd';
console.log(str.length);//new String('abcd').length;

2、其二:Number

var num = 123;
num.name='abc';//new Number(123).name='abc';-->delete
console.log(num.name);//undefined

练习题一

var arr=[1,2,3,4];
arr.length=2;//设置length后会截断
console.log(arr)

var str = "abcd";
// new String('abcd').length=2;-->delete
str.length = 2;
console.log(str);
console.log(str.length);

练习题二

var str='abc';
str += 1;
var test = typeof(str);
if(test.length==6){
	// new String(test).sign='';
	test.sign='typeof的返回结果可能为String';
}
// new String(test).sign
console.log(test.sign);

八、原型

知识点

prototype:原型,原型是系统内部的隐式属性,只能是系统给了,我们自己添不能用。
prototype{}:是祖先

  1. 定义:原型是function对象的一个属性,它定义了构造函数制造出的对象的公共祖先。通过该构造函数产生的对象,可以继承该原型的属性和方法。原型也是对象。
  2. 利用原型的特点和概念,可以提取共有属性。
  3. 对象如何查看原型:隐式属性__proto__
  4. 对象如何查看对象的构造函数:constructor

练习题一

Person.prototype.name = "sunny";
function Person(){
	
}
var person = new Person();
Person.prototype.name = "cherry";
console.log(person.name);

上述代码输出:cherry

Person.prototype.name = "sunny";
function Person(){
	
}
var person = new Person();
Person.prototype = {
	name: 'cherry'
};
console.log(person.name);

上述代码输出:sunny

Person.prototype.name = "sunny";
function Person(){
	
}
Person.prototype = {
	name: 'cherry'
};
var person = new Person();
console.log(person.name);

上述代码输出:cherry

九、原型链

  • 如何构成原型链,示例:grand,father,son
  • 原型链上属性的增删改查,与原型相似,就近原则,只有本人具有增删改查的权限,不能通过子孙进行操作。
  • Object.create(原型),也可以构造对象。
  • 所有对象的最终都会继承自Object.prototype,这句话是错误的,如Object.create(null)就不会。

十、call和apply

this指向是,谁调用的这个方法,this就指向谁

作用:改变this指向
区别:传参形式不同, call需要把实参按照形参的个数传进去
   apply需要传一个arguments数组列表

十一、继承(extends或inherit)

//圣杯模式
/*function inherit(Target, Origin){
	function F(){};
	F.prototype = Origin.prototype;
	Target.prototype = new F();
	Target.prototype.constructor = Target;
	Target.prototype.uber = Origin.prototype;
}*/
//上面是基本写法,可以引申出下面这种高级的写法
var inherit = (function(){
	var F = function (){};
	return function(Target, Origin){
		F.prototype = Origin.prototype;
		Target.prototype = new F();
		Target.prototype.constructor = Target;
		Target.prototype.uber = Origin.prototype;
	}
}());

Father.prototype.lastName = '张三';
function Father(){
	
}
function Son(){
	
}

//son继承father的lastName属性,并且给son添加age属性不会影响father
inherit(Son, Father);
var son = new Son();
var father = new Father();
son.age=18;
console.log(son.lastName+":"+son.age);
console.log(father.lastName+":"+father.age);

十二、this

  1. 函数预编译过程this指向window
  2. 全局作用域里this指向window
  3. call/apply可以改变函数运行时this指向
  4. obj.func();这里指向obj,谁调用的this指向谁

练习题一

var name = "222";
var a = {
	name: '111',
	say: function(){
		console.log(this.name);
	}
}
var fun = a.say;
fun();//22
a.say();//111

var b = {
	name: '333',
	say: function(){
		fun();
	}
}
b.say(a.say);//222
b.say = a.say;
b.say();//333

练习题二

var foo = '123';
function print(){
	var foo = '456';
	this.foo = '789';
	console.log(foo);
}
print();//456

练习题三

var foo = 123;
function print(){
	this.foo = 234;
	console.log(foo);
}
print();//234
//new print();//123

练习题四

var a=5;
function test(){
	a=0;
	console.log(a);
	console.log(this.a);
	var a;
	console.log(a);
}
//执行test()和new test()分别输出什么?
//test();// 0 5 0
new test();// 0 undefined 0

十三、数组,散列模式

1、定义方式

  1. [] 字面量,推荐
  2. new Array()

2、sort实现排序

  1. 必须写俩形参
  2. 看返回值:当返回值为负数时,那么前面的数在前
         当返回值为正数时,那么后面的数在前
         为0时,不动
var arr = [20,2,10,13,4,8,9];
arr.sort(function (a, b){
	return a-b;//升序
	//return b-a;//降序
});
console.log(arr);

十四、类数组:是对象,可以当数组使用

  1. 可以利用属性名模拟数组的特性
  2. 可以动态的增长length属性
  3. 如果强行让类数组调用push方法,则会根据length属性值的位置进行属性的扩充

类数组所具备的特性:

  1. 属性要为索引(数字)属性
  2. 必须有length属性,最好加上push()
  3. 最好有splice()
var obj = {
	'2': 'a',
	'3': 'b',
	'length': 2,
	'push': Array.prototype.push
}
//push时会执行下面的push方法
obj.push('c');//obj[2]=c;length++
obj.push('d');//obj[3]=d;length++
console.log(obj);//obj[2]=c,obj[3]=d,length=4

/*Array.prototype.push = function(target){
	obj[obj.length] = target;
	obj.length ++;
}*/

十五、其它小知识点

1、运算符优先级:=最弱,()优先级较高

2、逗号操作符,返回逗号后面的

var a = (1-1, 1+1);  
console.log(a);
var f=(
	function f(){
		return "1";
	},
	function g(){
		return 2;
	}
)();
console.log(typeof(f));

3、JS精度不准,可正常计算的范围(小数点前16位,后16位)

console.log(0.14*100); // 结果不是14
生成随机数时可以用向上取整/向下取整来避免这个问题

4、未经申明的变量,只有放到typeof才不报错

var x=1;
if(function f(){}){
	//f在这里是未经申明的变量,所以为undefined
    x += typeof f;
}
//输出结果为:1undefined
console.log(x);

5、Error.name的六种值对应的信息

  1. EvalError:eval()的使用与 不一致
  2. RangeError:数值越界
  3. ReferenceError:非法或不能识别的引用数值
  4. SyntaxError:发送语法解析错误
  5. TypeError:操作数据类型错误
  6. URIError:URI处理函数使用不当

6、ES5.0严格模式:use strict

现在的浏览器基于es3.0和es5.0新增的部分,如果两者冲突默认使用es3.0

两种用法:全局严格模式
     局部函数内严格模式(推荐)

“use strict”:不再兼容es3的一些不规则语法,使用全新的es5规范

  1. 不支持with,arguments,callee,func,caller
  2. 变量赋值前必须声明
  3. 局部的this必须赋值,赋值什么就是什么
  4. 拒绝重复属性和参数

7、命名空间

作用:管理变量,防止污染全局,适用于模块化开发。

命名空间用到的技术:
1、立即执行函数,执行过后立即销毁,不会污染全局变量。
2、闭包,产生私有化变量,不会污染全局;还可以把我们还要适用的内部方法保留到外部,来实现一些方法的调用。

8、属性表示方法

obj.name等同于obj[‘name’];
obj.name效率慢,需要先转换为obj[‘name’];

9、对象的枚举enumeration

for in 遍历

  • hasOwnProperty:可以过滤原型上的属性
  • instanceof:看A对象的原型链上有没有B的原型
  • in
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值