文章目录
计算正方形周长面积代码优化
for循环里分号连接,let
width:widthList[i]
是分号,属性:属性值,等于号赋值
内存浪费分析:for循环里i一直在变,在栈里改变
对于空数组,从第0->11个,必须新生成一块内存,其中的两个函数每次需要新生成,造成
let squareList=[];
let widthList=[1,2,5,7,9];
for(let i=0;i < 5;i++){
squareList[i]={
width:widthList[i],
getArea(){
return this.width*this.width
},
getLength(){
return this.width*4
}
}
}
借助原型
此时squareList.__proto__.__proto__===Object.prototype
let squareList = []
let widthList = [5,6,5,6,5,6,5,6,5,6,5,6]
for(let i = 0; i<12; i++){
squareList[i] = {
width: widthList[i],
getArea(){
return this.width * this.width
},
getLength(){
return this.width * 4
}
}
}
抽离成构造函数
封装:把细节写到一个函数中去
let squareList = []
let widthList = [5,6,5,6,5,6,5,6,5,6,5,6]
function createSquare(width){ //构造函数
let obj = Object.create(squarePrototype)
// 为原型squarePrototype创造空对象
obj.width = width
return obj
}
let squarePrototype = {
getArea(){
return this.width * this.width
},
getLength(){
return this.width * 4
}
}
for(let i = 0; i<12; i++){
squareList[i] = createSquare(widthList[i])
// square
}
函数与原型结合
createSquare.squarePrototype 点语法,函数也是对象
使用时才算使用
-
new操作符
规定好的,每个js函数有prototype属性,里面存在constructor
let squareList = [] let widthList = [5,6,5,6,5,6,5,6,5,6,5,6] function Square(width){ this.width = width } Square.prototype.getArea = function(){ return this.width * this.width } Square.prototype.getLength = function(){ return this.width * 4 } for(let i = 0; i<12; i++){ squareList[i] = new Square(widthList[i]) console.log(squareList[i].constructor) }
f1.prototype.constructor===f1
function F1(){}
undefined
console.dir(F1)
arguments: null
caller: null
length: 0
name: "F1"
prototype:
constructor: ƒ F1()
__proto__: Object
__proto__: ƒ ()
new X()做了那几件事
- 自动创建新对象,此时是空对象
- 自动将空对象关联他的原型,指定为X.prototype
- 将空对象作为this关键字运行构造函数
- 自动返回return this
构造函数X做了哪2件事
- X函数给自己添加自身属性
- X.prototype对用于保存对象的共有属性
function Dog(name){this.name=name,this.color='yellow',this.gender='女'};
Dog.prototype.run=function(){console.log('跑起来')};
Dog.prototype.say=function(){console.log('汪汪')};
let dog3=new Dog('小花')
代码规范:
- 大小写:
所有构造函数首字母大写
所有被构造出来的对象,首字母小写
-
词性:
new后面函数,使用名词形式如new Object(),如构造函数创造一类对象
其他函数,一般动词开头,如creatSquare(5)
x.prototype:#309 即原型的地址
属性只能够存基本类型变量,如string,number,对象的地址,对象存不了
公式
你是谁构造的,你的原型就是谁的prototype对应的对象
X.__proto__===其构造函数的.prototype
如:let a={}
原型是什么:Object.Prototype对象
内存图:window里有个Object属性,存着一个地址,这个地址对应window.Object的值,里面有prototype属性,对应原型的地址,即属性和他的值是两个东西
特殊值:Object.prototype是由哪个函数构造的:
他没有爸爸妈妈,没有原型,Object.prototype.__proto__为null,他只是个简单对象而已
构造函数算圆的周长面积
错误点在于:加共有属性=function(){}
圆的半径平方Math.pow(this.radius,2)*Math.PI
和π
function Cricle(radius){
this.radius=radius
}
Cricle.prototype.getArea=function(){
return Math.pow(this.radius,2)*Math.PI}
Cricle.prototype.getLength=function(){
return 2*this.radius*Math.PI}
let x=new Cricle(5)
x.getArea()
78.53981633974483
x.getLength()
31.41592653589793
对象需要分类
理由
有很多对象有一样属性和行为,归为一类,在创造类似新对象很方便
很多对象有其他属性和行为,就要分不同类
如Array/Function…
其中Object创造的对象最没有特点 如let a={}
类型VS类
类型是对js数据分成七种
类是针对对象的分类 无数种数组、函数、正则…
数组对象
1.新建一个数组
let a=[3,2,1] //最简单
let a=new Array(1,2,3)//三个元素
let a=new Array(3) //长度为3
2.数组对象的自身属性
'0‘/’1’/‘2’/‘3’/length
是字符串不是数字
Object.keys(a)
(3) ["0", "1", "2"]
0: "0"
1: "1"
2: "2"
length: 3
__proto__: Array(0)
3.数组对象的共有属性
数组对象比正常对象多一层共有属性
push是推,即从最后添加元素并返回数组长度
pop是弹出,即从最后删除元素并返回弹出的属性值
shift是提档,从第一个删除并返回数组长度
unshift是降档,从第一个添加元素并返回数组新长度
join是联合,数组连起来成字符串了,并返回字符串
Array.prototype.concat(),合并数组,不会更改当前数组
arr.push(4)
4
arr
(4) [1, 2, 3, 4]
arr.pop()
4
arr
(3) [1, 2, 3]
arr.shift()
1
arr
(2) [2, 3]
arr.unshift(6)
3
arr
(3) [6, 2, 3]
arr.join('喻')
"6喻2喻3"
const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = array1.concat(array2);
console.log(array3);
// expected output: Array ["a", "b", "c", "d", "e", "f"]
函数对象
1.函数对象写法4种
let fn3=new Function('x','y','return x+y')
let fn2=(x,y)=>{return x+y}
function fn1(x,y){return x+y}
let fn=function f2(x,y){return x+y}
2.函数对象的自身属性
‘name’和’length’
3.函数对象的共用属性
后期看
终极一问
1.window由谁构建出来的
Window 可以查看constuctor查看
2.window.Object由谁构造
- window.Function
- 所有函数有window.Function
- 可以查看constuctor查看
3.window.Function由谁创造?
所有函数都是window.Function
浏览器构造了Function,指定构造者是自己
let fn=new Function('x','y','return x+y')
fn.name
"anonymous"
fn.length
2
window.constructor
ƒ Window() { [native code] }
window.__proto__===Window.prototype
true
window.Object.constructor
ƒ Function() { [native code] }
window.Object.__proto__===window.Function.prototype
true
Class类(es6)
class Rect{
constructor(width, height){
this.width = width
this.height = height
}
getArea(){
return this.width*this.height
}
getLength(){
return (this.width + this.height) * 2
}
}
let react = new Rect(4,5)
https://fangyinghang.com/es-6-tutorials/
原型方法实现:
function Person(你来补全代码){
你来补全代码
}
let person = new Person('frank', 18)
person.name === 'frank' // true
person.age === 18 // true
person.sayHi() // 打印出「你好,我叫 frank」
let person2 = new Person('jack', 19)
person2.name === 'jack' // true
person2.age === 19 // true
person2.sayHi() // 打印出「你好,我叫 jack」
思路先构造函数,再用this加自身即新对象属性,对原型加共有属性,常为函数
function Person(name,age){
this.name=name
this.age=age
}
Person.prototype.sayHi=function(){
console.log('你好,我是'+this.name)
}
let person = new Person('frank', 18)
class方法实现:
相对于原型方法,直接在constructor里加自身属性,在函数外创建函数对象
class Person{
constructor(name, age){
this.name = name
this.age = age
}
sayHi(){
console.log('你好,我是'+this.name)
}
}