JS高级M

轮播图步骤:

第一步: 结构 结构牢记
第二步:css 外面小盒子根据图片的宽度进行设置 内部大盒子 宽度是根据图片的个数进行的设置的
第三步: js行为

//1、点击按钮让图片先动起来(只点击右侧)   每次点击要准备走的距离都是-600,这个距离需要用定时器慢慢走,
//	需要求每一步的距离     元素起始位置我们是可以获取到的, 结束位置我们也求出来;
			
//2、 看什么时候元素停止,当刚好元素走的位置和开启求出来的结束位置一样的时候,停止定时器;
			
//3、左边按钮和右边按钮    几乎一致,  只是点左边按钮的时候,元素要准备走的距离是600,其它的都不变,因此封装函数move(flag)
	函数传参为true就是点右  false就是点左
				
//4、无缝的操作     结构需要变化   最前面加最后一张    最后面加第一张; 在清除定时器的时候,去判断是否元素走到了最后一张的位置和第一		张的位置,如果走到,让元素瞬变到相应的位置
				
//5、小圆点变色  排他   关键点在求出哪一个小圆点变色,就是要拿到小圆点变色的下标,通过元素最终位置去求
			
//6、点击小圆点,图片移动对应位置  要传递元素准备移动的最终位置  跟点击的小圆点下标相关,move里面参数要根据类型进行判断
	//到底是点的按钮还是点的小圆点,因为传过来的参数不同
			
//7、自动轮播 ,  根据图片的下标进行move  传的也是元素准备移动的最终位置, 下标需要进行判断   为6  变回1
			
//8、自动轮播鼠标行为的同步   鼠标移入清除自动轮播   鼠标移出重启自动轮播   
			
			
//9、移入之后,鼠标点击按钮或者小圆点,都要去把自动轮播的下标值 进行更新, 否则没法同步;

一、内存、变量、数据

内存

计算机:cpu(寄存器)  内存  硬盘   电源  
硬件内存条:
	二极管    
	4G   4G字节   
	存储1或者0(通电和不通电) 
	内存地址(内存编号)
	内存的东西断电消失
	硬盘的东西永久性存储

运行内存(虚拟内存):(了解)


内存结构:栈内存和堆内存 (c语言、java)  
	  但是在js当中所有的内存都属于堆内存    然后在堆内存内部又分为栈结构和堆结构  
	var a = 10;
	a作为window对象的属性
	window又是一个对象,对象肯定是在堆结构当中的  

变量
可以变化的量
程序和进程
变量:可以变化的量:就是存储数据的容器;
var a = 5,b = 10;
var a = 5;
var b = 10;
本质上是内存空间

数据
分类(2大类)
* 基本(值)类型
* Number: 任意数值
* String: 任意文本
* Boolean: true/false
* undefined: undefined
* null: null

	* 对象(引用)类型
			* Object: 任意对象
			* Array: 一种特别的对象类型(下标/内部数据有序)
			* Function: 一种特别的对象类型(可执行)
			备注:准确来说Array和Function属于一种特别的Object类型。


**数据存储**
	基本数据存储    数据本身
	对象数据存储    地址值
	备注:内存当中存储的都是值,一个存的是数据本身,另一个存的是数据所在的内存(堆结构)地址;
				


**鉴别数据类型:**
	* typeof:注意typeof的返回值是类型的字符串名称(首字母是小写的)
	* 可以区别: 数值, 字符串, 布尔值, undefined, function
		* 不能区别: null与数组、对象
		* 对于typeof:
      		* 一个不正确:typeof null的结果是object
      		* 一个不精确:typeof []的结果是object

	* instanceof: A instanceof B ==> 判断A是否是B这个构造函数的实例对象(B是构造函数名)
			* 专门用来判断对象数据的具体类型: Object, Array

	* ===
			* 可以判断: undefined和null
			* 备注:因为undefined类型只有一个值、null类型也只有一个值,所以可以用===判断


所有数据类型转化布尔值:
	* 主要是处理  if(){};    

		基本数据类型:
			‘’ 0  NaN  undefined  null  false
		对象数据类型:
			 全是true
		*备注:js当中只有6个false值,其余全是true;



所有的数据类型进行判等 ==

	*基本数据类型
		如果是同种的基本数据类型,那么就直接比较两个值是否一样
		如果是不同的基本数据类型,那么两个值都要去转数字;
		*备注:当出现undefined和null的时候,他们两个是相等的;

			0和null
			''和null
			false和null  全都不等
		  
	*对象数据类型
		所有的对象去比较,比较的是地址,如果引用(地址)相同就相等;

		[] == [];
		[] == ![];

		


	*基本数据类型和对象数据类型之间的转化;
		对象数据类型和基本数据类型之间进行比较、判等和运算的时候,需要将对象数据类型转化基本数据类型,再按照基本数据类型的规			则进行运算
		对象数据类型转基本数据类型规则:
		1、首先看对象能不能转化为一个基本值类型  看看对象能不能使用valueOf方法转化一个基本值类型,调用的全是Object的原型对象				当中的valueOf方法;
		2、我们发现所有的对象在调用valueOf方法的时候都返回自身;
		3、如果对象调用valueof方法返回的不是基本值类型,那么会接着调用toString方法转化基本值;

	*备注:在真正开发当中我们很少去处理不同数据类型之间的判等,因此推荐在判等的时候使用===



面试题:
	//对象类型数据的判断
	var b1 = {
			b2:[2,'atguigu',console.log],
			b3:function () {
  				alert('hello')
			}
	}

	console.log(b1,b1.b2,b1.b3)//
	console.log(b1 instanceof Object,typeof b1)//
	console.log(b1.b2 instanceof Array,typeof b1.b2)//
	console.log(b1.b3 instanceof Function,typeof b1.b3)//
	console.log(typeof b1.b2[2])
	console.log(typeof b1.b2[2]('atguigu'))//



1. undefined与null的区别?
	* undefined代表定义变量没有赋值    var a;
	* null代表赋值了, 只是值为null     var a = null;


2. 什么时候给变量赋值为null呢?
	对象初始化
	删除对象   obj = null  ==》 obj变为垃圾对象  
	

3. 严格区别变量类型与数据类型?(js中了解行了)
	在c语言当中 变量也是有类型的      int a = 10; char a     float a;

	在js当中,变量类型是弱类型, 只有在数据确定存储之后,变量类型才确定  而且可以改变;(根据存储数据类型的不同而不同);



关于引用变量赋值问题

	1). 2个引用变量指向同一个对象, 通过一个引用变量修改对象内部数据, 另一个引用变量也看得见

		var arr1 = [1,2,3];
		var arr2 = arr1;
		arr1[1] = 22;
		console.log(arr2); 

		
	

	2). 2个引用变量指向同一个对象,让一个引用变量指向另一个对象, 另一个引用变量还是指向原来的对象
		var obj1 = {};
		var obj2 = obj1;
		obj2 = {};
		obj2.name = 'zhaoliying';
		console.log(obj1);
			
	

		

关于函数传参传值的问题
	传基本数据值
		var a = 10;
		var b = 20;
		function add(a,b){
			a = 20;
			return a + b;
		}
		add(a,b);
		console.log(a);

	传引用数据值
		
		var arr = [1,2,3];
		function fn(arr){
			arr[1] = 22;
		}
		fn(arr);
		console.log(arr);




关于内存释放(堆结构)的问题
	obj = null;
	垃圾回收机制:堆结构当中的对象数据,要想被回收释放,必须成为垃圾对象,也就是没有人再指向这个对象数据;

二、对象基础

1. 什么是对象?
	* 代表现实中的某个事物, 是该事物在编程中的抽象(无序的键值对的集合)
	* 多个数据的集合体(封装体)
 	* 用于保存多个数据的容器

	var obj = {

		name:'赵丽颖‘,
		age:33
		eat:funcition(){
			console.log('吃货');
		}
	}

	obj.eat();

	console.log()

2. 为什么要用对象?
	* 便于对多个数据进行统一管理
	* 为了去描述某个复杂的事物

3. 创建对象?
	* 

4. 对象的组成
	* 属性
			* 代表现实事物的状态数据
			* 由属性名和属性值组成
			* 属性名都是字符串类型, 属性值是任意类型	


	var obj = {name:'zly','name':'',"name":''}
		
	* 方法
		* 代表现实事物的行为数据
			* 备注:方法是一种特别的属性==>属性值是函数

5. 如何访问对象内部数据?
	* 对象.属性名: 编码简单, 但有时不能用

	var obj = {};
	obj["content-type"] = '12';
	var a = 10;
	obj[a]




	* 对象['属性名']: 编码麻烦, 但通用
	* 对象[变量名]:变量里面的值会被转化成字符串,作为属性名

	问题: 什么时候必须使用['属性名']的方式?
		* 属性名不是合法的标识符
		* 属性名是变量	

6、面试题
	var a = {};//
	var obj1 = {m:2}//
	var obj2 = {n:2}// [1,2,3]
	var obj3 = function(){};
	a[obj1] = 4       //   '[object Object]'    a['[object Object]'] = 4
	a[obj2] = 5     	'1,2,3'             a['1,2,3'] = 5
	a.name ='kobe'
	a[obj3] = 6;
	console.log(a[obj1])  5
	console.log(a)     // 
	a{
		1,2,3:5
		[object Object]:4,
		name:'kobe',
		function(){}:6
	}

三、函数基础
1. 什么是函数?
* 具有特定功能的n条语句的封装体
* 只有函数是可执行的, 其它类型的数据是不可执行的
* 函数也是对象
2. 为什么要用函数?
* 提高代码复用
* 便于阅读和交流
* 把一个项目模块化
3. 如何定义函数?
* 函数声明(字面量) function fn(){};
* 函数表达式 var fn = function(){};
构造函数 var add = new Function(‘a’,‘b’,‘return a + b’)//了解

4. 函数的2种角色
	* 函数: 通过()使用
		通过new和()使用
	* 对象: 通过.使用  ==> 称之为: 函数对象



5. 如何调用(执行)函数?
	* test()
	* new test()
	* obj.test()
	* test.call/apply(obj)



	
	
6、函数执行的过程(内存变化)


7、回调函数
	什么函数才是回调函数?
		* 你定义的
		* 你没有直接调用
		* 但最终它执行了(在特定条件或时刻)
	常见的回调函数?
		* DOM事件函数
		* 定时器函数
		* ajax回调函数(后面学)
		* 生命周期回调函数(后面学)

8、IIFE
	理解
		* 全称: Immediately-Invoked Function Expression 立即调用函数表达式
		* 别名: 匿名函数自调用
	作用
		* 隐藏内部实现
		* 不污染外部命名空间	
			

	案例:
		var a = 2
		var b = 3
		function sum(a,b) {
			return a + b
		}
		var a = 'haha';

		sum();

		


		var a = 'haha';
		(function () {
				var a = 2
				var b = 3
				function fn() {
  					return a + b
				                                                                                                                                                                                                                                                  				}
				window.fn = fn
		})()

		fn()


9、this的总结

	this是什么?
		* 一个关键字, 一个内置的引用变量
		* 在函数中都可以直接使用this
		* this代表调用函数的当前对象(函数的调用者)
		* 在定义函数时, this还没有确定, 只有在执行时才动态确定(绑定)的

	function fn(){};     fn()     fn.call(obj);
	
	
	

	如何确定this的值?
		* test()
		* obj.test()
		* new test()
		* test.call/apply(obj)
	总结: 函数的调用方式决定了this是谁

	this的出现场合: 函数中   方法中   事件中    构造函数中      call/apply()


10、递归(后面说)	

四、执行上下文、执行上下文栈、预解析、作用域、作用域链、 (打断点)

执行上下文(执行上下文环境):
	程序在解析和运行的时候所依赖和使用的环境;


执行上下文栈:
	程序为了管理执行上下文(确保程序的执行顺序)所创建的一个栈数据结构,被称作执行上下文栈;



预解析(变量提升):
	先解析函数:函数重名覆盖
	再解析变量:变量重名忽略

作用域:(抽象的概念,代码定义的时候作用域就确定死了)
	变量起作用的范围;
	作用域;隔离变量,防止变量命名污染;
	
	作用域定义时候确定

作用域链:
	真实存在的,作用域链是使用执行上下文当中变量对象所组成的链条结构(数组结构)
	
	查找的时候其实真正是先去自身的变量对象当中查找,如果没有,去上级执行上下文的变量对象当中去查找,直到找到全局执行上下文的变量对象;  函数上一级的变量对象其实是在函数定义的时候都已经确定好的******


程序开始执行:(全局环境和函数环境)


全局执行上下文(分为创建阶段和执行阶段)代码开始执行之前和之后
	1、全局执行上下文压入执行上下文栈)
		创建上下文阶段(确定作用域):
			1、收集变量形成变量对象 函数 var的变量会收集
			   预解析(其实在创建变量对象的时候已经做了预解析)
			
			2、确定this指向(可以认为确定执行者)
			3、创建自身执行上下文的作用域链
				 注意:同时确定函数在调用时候的上级作用域链。(根据ECMA词法去确定,看内部是否引用外部变量确定)

	2、执行全局执行上下文
		执行全局上下文阶段
			为变量真正赋值
			顺着作用域链查找要使用的变量或者函数执行
函数执行上下文
	1、函数执行上下文压栈
			1、收集变量  var 形参  arguments  函数
			
			
			函数的作用域链:  自己定义的时候已经确定了函数在调用时候的上级作用域链,因此,在函数调用的时候,只需要将	
					自己的变量对象添加到作用域的顶端;
			2、执行函数执行上下文
			


全局:创建全局执行上下文--全局执行上下文压栈--执行全局执行上下文--
函数:创建函数执行上下文--函数执行上下文压栈--执行函数执行上下文--函数执行上下文出栈--
执行全局执行上下文--全局执行上下文出栈


创建全局上下文:1、收集变量形成变量对象(预解析)2、确定this指向 3、创建自身作用域链(同时函数确定调用的上级作用域链)



//预解析  作用域链面试题	

var x = 10;
function fn() {
		console.log(x);//10
}
function show(f) {
		var x = 20;
		f();
}
show(fn);

var a;
function a() {}
	
console.log(typeof a)//function

if (!(b in window)) {
		var b = 1;
}
console.log(b)//undefined

var c= 1  	

function c(c) {
		console.log(c)
		var c = 3
}


c(2) //c is not a function

var fn = function () {
		console.log(fn)
}
fn()

var obj = {
		fn2: function () {
  			console.log(fn2)//
		}
}
obj.fn2()

五、闭包(面试题)
1. 如何产生闭包(条件)?
* 函数嵌套
* 内部函数引用外部函数的局部变量
* 调用外部函数,调用或者引用内部函数;
2. 闭包到底是什么?
* 理解一: 闭包是嵌套的内部函数(绝大部分人)
* 理解二: 包含被引用变量(外部函数)的对象(极少数人)
* 理解三: 所谓的闭包是一个引用关系,该引用关系存在于内部函数中,引用的是外部函数的变量的对象(深入理解)

3、常见的闭包
	1. 将函数作为另一个函数的返回值
	2. 将函数作为实参传递给另一个函数调用
	3. 使用闭包实现私有方法操作独立的私有属性
4、闭包的作用
	1. 延长外部函数变量对象的生命周期
	2. 让函数外部可以操作(读写)到函数内部的数据(变量/函数)
	3. 注意: 浏览器为了性能后期将外部函数中不被内部函数使用的变量清除了

5、闭包的生命周期
	1. 产生: 在嵌套内部函数定义执行完时就产生了(不是在调用)
	2. 死亡: 在嵌套的内部函数成为垃圾对象时

6、自定义模块	
	* 具有特定功能的js文件
	* 将所有的数据和功能都封装在一个函数内部(私有的)
	* 只向外暴露一个包含n个方法的对象或函数
	* 模块的使用者, 只需要通过模块暴露的对象调用方法来实现对应的功能
	使用window和不使用window区别:两种都使用的是闭包思想;
		使用window会污染window对象的属性

		

7、闭包的缺点和解决(内存泄漏和内存溢出)
	闭包是一把双刃剑:有优点也有缺点;
	优势:
		1. 延长外部函数变量对象的生命周期
		2. 让函数外部可以操作(读写)到函数内部的数据(变量/函数)
	缺点:
		会造成内存泄漏,甚至导致内存溢出;
		内存泄漏:代表对象占着内存,不会释放
		内存溢出:代表不会释放的东西太多,导致内存满了;
	一般我们再使用闭包的时候,不用的时候记得把内部函数变为垃圾对象,这样就可以防止内存泄漏;

8、面试题

	//代码片段一
	var name = "The Window";
	var object = {
			name: "My Object",
			getNameFunc: function () {
			
  				return function () {
    				return this.name;
  				};
		     	}
	};
	console.log(object.getNameFunc()()); //the window 

	//代码片段二
	var name2 = "The Window";
	var object2 = {
			name2: "My Object",
			getNameFunc: function () {
  				var that = this;
  				return function () {
    				return that.name2;
  				};
			}
	};
	console.log(object2.getNameFunc()());//	"My Object"


	 //代码片段三

	function fun(n, o) {
			console.log(o)
			return {
  				fun: function (m) {
    				return fun(m, n)
  				}
			}
	}


	var a = fun(0)  //undefined
	a.fun(1)  //0
	a.fun(2) //0
	a.fun(3) //0


	var b = fun(0).fun(1).fun(2).fun(3) //undefined 0 1 2 


	var c = fun(0).fun(1)//undefined  0
	c.fun(2)//1
	c.fun(3) //1


	//代码片段四
	function Foo() {
			getName = function () { alert (1); };
			return this;
	}
	Foo.getName = function () { alert (2);};
	Foo.prototype.getName = function () { alert (3);};
	var getName = function () { alert (4);};
	function getName() { alert (5);}

	//请写出以下输出结果:
	Foo.getName();
	getName();
	Foo().getName();
	getName();
	new Foo.getName();
	new Foo().getName();
	new new Foo().getName();

六、原型和原型链、终极原型链

七、面向对象(原型继承、构造函数继承、组合继承) 面向对象三大特性:封装继承多态

原型继承:
	让父类的实例作为子类的原型,将子类的原型构造器补充完整 (为了让子类继承方法)


构造函数继承:
	在子类当中去调用父类的构造函数(为了让子类继承属性)


组合继承:
	原型继承方法,构造函数继承属性


方法重写(多态的表现形式之一)

方法重载	

八、事件循环机制
多进程和多线程
1. 进程:程序的一次执行, 它占有一片独有的内存空间
2. 线程: CPU的基本调度单位, 是程序执行的一个完整流程
3. 进程与线程
* 一个进程中一般至少有一个运行的线程: 主线程
* 一个进程中也可以同时运行多个线程, 我们会说程序是多线程运行的
* 一个进程内的数据可以供其中的多个线程直接共享
* 多个进程之间的数据是不能直接共享的

	4. 浏览器运行是单进程还是多进程?
		* 有的是单进程
				* firefox
				* 老版IE
		* 有的是多进程
				* chrome
				* 新版IE
	5. 如何查看浏览器是否是多进程运行的呢?
		* 任务管理器==>进程

	6. 浏览器运行是单线程还是多线程?
		* 都是多线程运行的

js是单线程的
	1. 如何证明js执行是单线程的?
		* setTimeout()的回调函数是在主线程执行的
		* 定时器回调函数只有在运行栈中的代码全部执行完后才有可能执行
	2. 为什么js要用单线程模式, 而不用多线程模式?
		* JavaScript的单线程,与它的用途有关。
		* 作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。
		* 这决定了它只能是单线程,否则会带来很复杂的同步问题

	3. 代码的分类:
		* 初始化代码(同步代码)
		* 回调代码

	4. js引擎执行代码的基本流程
		* 先执行初始化代码: 包含一些特别的代码
			* 设置定时器
			* 绑定监听
			* 发送ajax请求
		* 后面在某个时刻才会执行回调代码

同步    同步执行完成才会去执行异步

异步	只要是异步的任务都会有自己的管理模块进行托管

回调
	事件
	定时器
	ajax

事件循环模型

	1. 所有代码分类
		* 初始化执行代码(同步代码): 包含绑定dom事件监听, 设置定时器, 发送ajax请求的代码
		* 回调执行代码(异步代码): 处理回调逻辑
	2. js引擎执行代码的基本流程:
		* 初始化代码===>回调代码
	3. 模型的2个重要组成部分:
		* 事件管理模块
		* 回调队列
	4. 模型的运转流程
		* 执行初始化代码, 将事件回调函数交给对应模块管理
		* 当事件发生时, 管理模块会将回调函数及其数据添加到回调列队中
		* 只有当初始化代码执行完后(可能要一定时间), 才会遍历读取回调队列中的回调函数执行


Web Workers模拟多线程(了解~)
	1. H5规范提供了js分线程的实现, 取名为: Web Workers
	2. 相关API
		* Worker: 构造函数, 加载分线程执行的js文件
		* Worker.prototype.onmessage: 用于接收另一个线程的回调函数
		* Worker.prototype.postMessage: 向另一个线程发送消息

		每个线程可以向不同线程发送消息  也可以接收不同线程传来的消息
		
		主线程操作
			发送消息:   worker.postMessage(消息可以是任何数据)
			接受消息:   worker.onmessage = function(e){
					console.log(e.data)//接收到的消息或者数据在事件对象的data属性当中
			    	    }

	
		子线程操作
			发送消息:   this(self).postMessage(消息可以是任何数据)
			接受消息:   this(self).onmessage = function(e){
					console.log(e.data)//接收到的消息或者数据在事件对象的data属性当中
			     	    }
		
					
	3. 不足
		* worker内代码不能操作DOM(更新UI)
		* 不能跨域加载JS
		* 不是每个浏览器都支持这个新特性


	4、计算得到fibonacci数列中第n个数的值
		在主线程计算: 当n的数较大时, 会阻塞主线程, 导致界面卡死
		在分线程计算: 不会阻塞主线程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值