review
// 单例模式 命名空间
let zhangsan = {
name:" "
}
// 高级单例 用一个函数返回一个对象
let lisi = (function () {
let count = 100
return {
add() {
console.log(count++)
}
}
})()
let home = (function () {
})()
// 工厂模式
function factory(name, age, flag = false) {
if (flag) {
name = name + 'AAA'
}
return {
name,
age
}
}
let p1 = factory("张家界", 100, true)
let p2 = factory("香山", 100)
// 构造函数模式
function Person(name, age) {
this.name = name;
this.age = age;
}
letp3 = newPerson('账单', 123)
// 原型模式
function Student(name, age) {
this.name = name;
this.age = age;
}
// Student这个类的原型上存放的 属性,都是供 Student的实例去使用的公用属性
Student.prototype.study = function () {
// study这个方法 是Student的实例能有调用
}
let p4 = newStudent('账单', 123)
/*
new 执行的过程:
先开作用域, 开一个堆内存,让函数中的this指向这个堆;
然后 形参赋值 变量提升;
然后代码从上到下执行;
return的问题
return 后边跟一个引用类型 则返回的就是写的这个引用类型
否则返回时这个堆内存(this-->实例)
*/
/*
this 箭头函数的this去上级作用域查找;
事件绑定 this就是绑定的元素
自执行 和 定时器对应的回调函数 中的this 是window;
全局下的this是window
看点 点前边是谁 this就是谁 (this 函数的执行主体);没点就是window
严格模式 "use strict" 不指定就是undefined
*/
/*
函数都有prototype,里边用来存储实力能够使用的公用属性
自带的(默认的)的prototype上都有 constructor ; 指的是 这个构造函数本身
所有的实例 都有一个__proto__ 指向所属类的prototype
实例去调用某个属性的时候
实例.xxxx
先在自己身上查找这个属性,没有的话,通过__proto__向上层对象A 查找,
上层对象A若也没有这个属性,则接着通过__proto__向A的上层对象B中查找,。。。。
一直找到基类(Object类)的原型(prototype),这时都没有对应的属性时,结果就是undefind
因为基类的prototype的 __proto__是null;也就是说基类的prototype是最顶层了;
以上通过__proto__向上查找属性的这个线路 称为原型链;
常见的内置类 或者 自己定义的类的原型 的 __proto__一般都是指向基类的原型
Array String Nubmer Boolean Function...
Student.prototype.__proto__ === Object.prototype
Object 基类
Array.prototype.__proto__ === Object.prototype
*/
constructor
[].constructor === Array;
({}).constructor === Object;
// constructor这个属性之所以能有用来判断数据类型
// 是因为实例调用constructor都是调用的原型上的constructor,指向就是构造函数本身
function isArray(option) {
return option.constructor === Array
}
// Array.isArray() es6新增的API
isArray([]) // true
isArray({}) // false
instanceof
/*
A instanceof B
从A到基类的原型,这条原型链上有没有B的原型存在;
特殊: 只能用于引用数据类型,值类型不适用;
*/
let ary = [];
var num = 1;
// console.log(num instanceof Number)
console.log(ary instanceof Number)
console.log(ary instanceof Array)
console.log(ary instanceof Object)
in
Array.prototype.myMap = function (cb) {
// myMap 的返回值是一个新数组 长度和this是一样的
// 新数组中的每一项都是由cb的返回结果决定的
let temp = [];
for (let i = 0; i < this.length; i++) {
let res = cb(this[i])
temp.push(res)
}
return temp
}
var ary = [111, 222, 333]
let res = ary.myMap(item=> {
// res 中的项 是由这个回调函数的返回结果决定的
return item
})
console.log(res)
</script>
<script src=''>
Array.prototype.myForEach = function (cb) {
// this --> ary
// cb 对应的是下方传递的回调函数
// 使用 for循环这个数组ary;然后执行回调cb
// 执行cb的时候 要把 数组中的项传给这个cb;
for (let i = 0; i < this.length; i++) {
cb(this[i])
}
}
var ary = [111, 2222, 3333]
ary.myForEach((item) => {
console.log(item)
})
</script>
<script src=''>
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.eat = false;
let p1 = newPerson('张三', false);
console.log(p1)
for (let k in p1) {
// console.log(p1.hasOwnProperty(k))
if (p1.hasOwnProperty(k)) {
console.log('属性名:', k, ' 属性值:', p1[k])
}
}
Object.keys(p1) // 把p1中的私有属性名都存放到一个数组当中 然后返回
Object.keys(p1).forEach(k=> {
console.log(k)
})
// obj.hasPubProperty(key) 看看key 是不是obj的公有有属性
Object.prototype.hasPubProperty123 = function (key) {
// this ---> p1 ; key 是不是this的共有属性
// 首先得是我们能够调用的属性 ,并且 不是私有的,这时才是公有的
// in 在JS中的翻译 直白点就是在 A in B : B是否能够调用A属性
return (key in this) && !this.hasOwnProperty(key)
}
p1.hasPubProperty123('eat') // false
p1.hasOwnProperty('name') // true
// 自己实现一个mypush 用法等同 push
Array.prototype.mypush = function (...args) { //[3,4,5,6,7]
// this --> ary // arguments
args.forEach(k=> {
this[this.length] = k
})
return this.length
}
var ary = [1, 2]
ary.mypush(3, 4, 5, 6, 7)
</script>
<script scr=''>
function Fn(x) {
let y = 20;
this.total = x + y;
this.say = function () {
console.log(`${x} + ${y} = ${this.total}`);
};
}
let f1 = Fn(10);
let f2 = newFn(10);
let f3 = newFn(20);
console.log(f2.total);
console.log(f2.x);
console.log(f3.y);
console.log(f1 === f2);
console.log(f2 === f3);
f2.say();
console.log(f2.say === f3.say);
// console.log(f1.total);
console.log(window.total);
window.say();
</script>
<script>
function fun() {
this.a = 0;
this.b = function () {
alert(this.a);
}
}
// 原型重写,需要注意constructor的指向问题
fun.prototype = {
constructor:fun,
b:function () {
this.a = 20;
alert(this.a);
},
c:function () {
this.a = 30;
alert(this.a)
}
};
var my_fun = new fun(); //{a:0,b:f}
my_fun.b(); // this 是 my_fun;;this.a-->my_fun.a
my_fun.__proto__.b()
console.log(my_fun.constructor)
</script>