赞
踩
基本(值)类型
对象(引用)类型
判断:
typeof:
instanceof
===
代码:
<script type="text/javascript"> //1. 基本类型 var a console.log(a, typeof a, a === undefined) // undefined 'undefined' true console.log(a === typeof a) // false undefined ≠ 'undefined' //typeof返回字符串类型 a = 3 console.log(typeof a === 'number') // true a = 'atguigu' console.log(typeof a === 'string') // true a = true console.log(typeof a === 'boolean') // true a = null console.log(a === null) // true console.log(typeof a) // 'object' console.log('--------------------------------') //2. 对象类型 var b1 = { b2: [2, 'abc', console.log],//number string function b3: function () { console.log('b3()') } } console.log(b1 instanceof Object, typeof b1) // true 'object' console.log(b1.b2 instanceof Array, typeof b1.b2) // true 'object' console.log(b1.b3 instanceof Function, typeof b1.b3) // true 'function' console.log(typeof b1.b2[2]) // 'function' console.log(b1.b2[2]('abc')) // 内'abc' 外undefined </script>
数据
变量
内存
内存,数据, 变量三者之间的关系
var a = xxx, a内存中到底保存的是什么?
xxx是一个基本数据,保存的就是这个数据
xxx是一个对象,保存的是对象的地址值
xxx是一个变量,保存的是xxx的内容
<script type="text/javascript"> // 创建对象 var p = {} /*情形一: 属性名不是合法的标识名*/ /*需求: 添加一个属性: content-type: text/json */ // p.content-type = 'text/json' //不正确 p['content-type'] = 'text/json' /*情形二: 属性名不确定*/ var prop = 'xxx'//变量 不确定 var value = 123 // p.prop = value //不正确 p[prop] = value console.log(p['content-type'], p[prop]) </script>
<script type="text/javascript">
function f1() { // 函数声明
console.log('f1()')
}
var f2 = function () { // 表达式
console.log('f2()')
}
f1()
f2()
</script>
为什么要用函数?
函数也是对象
函数的3种不同角色
函数中的this
<script type="text/javascript"> function Person(color) { console.log(this) this.color = color; this.getColor = function () { console.log(this) return this.color; }; this.setColor = function (color) { console.log(this) this.color = color; }; } Person("red"); //this是 windows var p = new Person("yello"); //this是 p p.getColor(); //this是 p var obj = {}; p.setColor.call(obj, "black"); //this是 obj var test = p.setColor; test(); //this是 windows function fun1() { function fun2() { console.log(this); } fun2(); //this是 windows } fun1(); </script>
匿名函数自调用
(function(w, obj){
//实现代码
})(window, obj)
(function (i) {
var a = 4
function fn() {
console.log('fn ', i+a)//fn 7
}
fn()
})(3)
回调函数
<script type="text/javascript">
//1. DOM事件函数
var btn = document.getElementById('btn')
btn.onclick = function () {
alert(this.innerHTML)
}
//2. 定时器函数
setInterval(function () {
alert('到点啦!')
}, 2000)
</script>
prototype
: 显式原型属性// 每个函数都有一个prototype属性, 它默认指向一个对象(即称为: 原型对象) function fn() { } console.log(fn.prototype, typeof fn.prototype)//object 'object' // 原型对象中有一个属性constructor, 它指向函数对象 console.log(fn.prototype.constructor===fn)//true // 2. 给原型对象添加属性(一般都是方法) function F() { } F.prototype.age = 12 //添加属性 F.prototype.setAge = function (age) { // 添加方法 this.age = age } // 创建函数的实例对象 var f = new F() console.log(f.age)//12 f.setAge(23) console.log(f.age)//23
__proto__
: 隐式原型属性 //对象的隐式原型的值为其对应构造函数的显式原型的值
function Fn() {
}
var fn = new Fn()
console.log(Fn.prototype, fn.__proto__)//object object
console.log(Fn.prototype===fn.__proto__)//true
console.log(Object.prototype instanceof Object)//false
console.log(Function.__proto__===Function.prototype)//false
Object的原型对象是原型链的尽头
instanceof
function Foo() { }
var f1 = new Foo();
console.log(f1 instanceof Foo);//true
console.log(f1 instanceof Object);//true
console.log(Object instanceof Function)//true
console.log(Object instanceof Object)//true
console.log(Function instanceof Object)//true
console.log(Function instanceof Function)//true
function Foo() {}
console.log(Object instanceof Foo);//false
var A = function() {
}
A.prototype.n = 1
var b = new A()
A.prototype = {
n: 2,
m: 3
}
var c = new A()
console.log(b.n, b.m, c.n, c.m)//1 undefined 2 3
var F = function () { };
Object.prototype.a = function () {
console.log('a()')
};
Function.prototype.b = function () {
console.log('b()')
};
var f = new F();
f.a()//a()
f.b()//报错 原型链找不到
F.a()//a()
F.b()//b()
/*变量提升*/
console.log(a1) //可以访问, 但值是undefined
/*函数提升*/
a2() // 可以直接调用
var a1 = 3
function a2() {
console.log('a2()')
}
function fn (a1){
console.log(a1)//2
console.log(a2)//undefined
a3()//a3()
console.log(this)//window
console.log(atguments)//伪数组(2,3)
var a2 = 3
function a3(){
console.log('a3()')
}
}
fn(2,3)
//1. 进入全局执行上下文
var a = 10
var bar = function (x) {
var b = 5
foo(x + b) //3. 进入foo执行上下文
}
var foo = function (y) {
var c = 5
console.log(a + c + y)
}
bar(10) //2. 进入bar函数执行上下文
/* 测试题1: 先预处理变量, 后预处理函数 */ function a() { } var a; console.log(typeof a)//function /* 测试题2: 变量预处理, in操作符 */ if (!(b in window)) { var b = 1; } console.log(b)//undefined /* 测试题3: 预处理, 顺序执行 */ var c = 1 //var c function c(c) { console.log(c) var c = 3 } //c = 1 c(2)//报错
var a = 10, b = 20 function fn(x) { var a = 100, c = 300; console.log('fn()', a, b, c, x) function bar(x) { var a = 1000, d = 400 console.log('bar()', a, b, c, d, x) } bar(100)//bar() 1000 20 300 400 100 bar(200)//bar() 1000 20 300 400 200 } fn(10)//fn() 100 20 300 10
var x = 10;
function fn() {
console.log(x);
}
function show(f) {
var x = 20;
f();
}
show(fn);//fn和show是同级函数
var fn = function () {
console.log(fn)//输出函数
}
fn()
var obj = {
fn2: function () {
console.log(fn2)//报错
//console.log(this.fn2)
}
}
obj.fn2()
理解:
作用:
常见的闭包
// 1. 将函数作为另一个函数的返回值 function fn1() { var a = 2; function fn2() { a++; console.log(a); } return fn2; } var f = fn1(); f();//3 f();//4 // 2. 将函数作为实参传递给另一个函数调用 function showMsgDelay(msg, time) { setTimeout(function () { console.log(msg) }, time) } showMsgDelay('hello', 1000)
闭包的生命周期
闭包应用:
缺点:
//代码片段一 var name = "The Window"; var object = { name: "My Object", getNameFunc: function () { return function () { return this.name; }; } }; console.log(object.getNameFunc()()); //The Window 直接执行函数,this指向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 that保存的是函数 有闭包
function fun(n, o) { console.log(o) return { fun: function (m) { return fun(m, n) } } } var a = fun(0) a.fun(1) a.fun(2) a.fun(3) //undefined,0,0,0 var b = fun(0).fun(1).fun(2).fun(3) //undefined,0,1,2 闭包 var c = fun(0).fun(1) c.fun(2) c.fun(3) //undefined,0,1,1 前面闭包,后面是因为闭包延长局部变量的生命周期
Object构造函数模式
//适用场景: 起始时不确定对象内部数据
//问题: 语句太多
var obj = {};
obj.name = 'Tom'
obj.setName = function(name){this.name=name}
对象字面量模式
//适用场景: 起始时对象内部数据是确定的
//问题: 如果创建多个对象, 有重复代码
var obj = {
name : 'Tom',
setName : function(name){this.name = name}
}
工厂模式
// 工厂函数: 返回一个需要的数据的函数
//适用场景: 需要创建多个对象
//问题: 对象没有一个具体的类型, 都是Object类型
function createPerson(name, age) {
var p = {
name: name,
age: age,
setName: function (name) {
this.name = name
}
}
return p
}
构造函数模式
//适用场景: 需要创建多个类型确定的对象
//问题: 每个对象都有相同的数据, 浪费内存
function Person(name, age) {
this.name = name;
this.age = age;
this.setName = function(name){this.name=name;};
}
new Person('tom', 12);
构造函数+原型的组合模式
//适用场景: 需要创建多个类型确定的对象
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.setName = function(name){this.name=name;};
new Person('tom', 12);
function Parent(){}
Parent.prototype.test = function(){};
function Child(){}
Child.prototype = new Parent(); // 子类型的原型指向父类型实例
Child.prototype.constructor = Child
var child = new Child(); //有test()
借用构造函数 : 得到属性,在子类型构造函数中通用super()调用父类型构造函数(关键)
function Parent(xxx){this.xxx = xxx}
Parent.prototype.test = function(){};
function Child(xxx,yyy){
Parent.call(this, xxx);//借用构造函数 this.Parent(xxx)
}
var child = new Child('a', 'b'); //child.xxx为'a', 但child没有test()
组合
function Parent(xxx){this.xxx = xxx}
Parent.prototype.test = function(){};
function Child(xxx,yyy){
Parent.call(this, xxx);//借用构造函数 this.Parent(xxx)
}
Child.prototype = new Parent(); //得到test()
var child = new Child(); //child.xxx为'a', 也有test()
new一个对象背后做了些什么?
可以让js在分线程执行
Worker
var worker = new Worker('worker.js');
worker.onMessage = function(event){event.data};// 用来接收另一个线程发送过来的数据的回调
worker.postMessage(data1);//向另一个线程发送数据
问题:
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。